Why won't my code do literally anything? - python

I'm trying to write some code to compute the thousandth prime number and when I thought I was done I tried to run it but nothing is happening. I don't get errors or anything that should happen according to the code, just literally nothing. I'm running it in windows powershell if that matters. the code is here below. (Python 2.7)
n = 1
all_odd_integers = 2*n+1
prime_number = 2 #cause 3 is the second prime
while prime_number < 1000: #a while loop to get to prime thousand
for i in range (2, (all_odd_integers-1)): #because I want to divide all_odd_integers by all numbers except 1 and itsself and nothing bigger, but bigger than 0
if all_odd_integers % i == 0:
n += 1
print "not a prime" #because, like, if a number can be divided without a reminder it's not a prime
else:
n = n+1
prime_number += 1
print "a prime" #because exactly the opposite of the if-clause, here there is a reminder so prime
if prime_number == 1000:
print "the thousandth prime is %d" (all_odd_integers)

Your code isn't working because you have an infinite while loop, since your for loop isn't even being executed. You almost have the approach right for calculating the primes however.
If you want to print out every prime number as your current code would if it worked, you can much more easily implement something like this :
counter = 1
prime = 3
while counter != 1000:
for x in range(2,prime):
if prime%x == 0:
break
else:
print(prime)
counter += 1
prime += 2
Alternatively, if you only want to print out the thousandth prime I'm sure there are a plethora of more efficient ways, but I would lean towards something like this for simplicity and decent efficiency:
from math import sqrt
counter = 1
prime = 1
while counter < 1000:
prime += 2
for x in range(2,int(sqrt(prime+1)) + 1):
if prime%x == 0:
break
else:
counter += 1
print (prime)

I think you're thinking about this too hard. There are some errors to your code, but really it can all be boiled down to:
counter = 1
n = 2
while True:
n += 1
if all(n % i for i in xrange(2, n)): counter += 1
if counter == 1000: break
print "the thousandth prime is {0}".format(n)
This loops through all numbers between 2 and itself to see if any of them return a 0 remainder when n is divided by them. If none do, it's a prime and counter gets ticked, if not then it goes on to the next number. Once it finds 1000 primes it breaks and prints the thousandth prime is 7919
Some of the things wrong with your code:
all_odd_integers never changes. So when you do for i in range(2, (all_odd_integers-1)) it will never run anything except for i in range(2, 2) which is 0 because range excludes the higher number. all_odd_integers = 2*n+1 is only run once, when all_odd_integers is defined, it doesn't change when n does.
Even if all_odd_integers did update, why would you multiply it by two? Wikipedia has a prime defined as:
A prime number (or a prime) is a natural number greater than 1 that has no positive divisors other than 1 and itself.
If n was 3 then all_odd_integers would be 7? Why would 3 need to be divided by 4-6?
Just a note: there is no need to check if prime_number is equal to 1000 at the end since that's why the code block broke.

What if you start with n=2 and prime_number = 3? that way you'll reach the for loop.

Like the other anwserers, the condition in the while loop never changes.
Look at your range() call:
range (2, (all_odd_integers-1))
When you call range, there is a start (2) and a stop (all_odd_integers-1).
range(1,5) generates: 1,2,3,4
Look at all_odd_integers:
all_odd_integers = 2*n+1
2*n+1 means 2*1+1 because n = 1 so 2*n+1 = 3 therefore you are calling range(2,2) which gives [] and then the loop is never executed at all.
EDIT: More things
This function gives you your odd integers.
def odd_integers():
odd_integers = []
for i in xrange(1001):
if i/2 != int(i/2);
odd_integers.append(i)
return odd_integers
Here's your new for:
for i in odd_integers():

The condition in your while loop is always true. prime_number doesn't ever change. Look again at your code
for i in range (2, (all_odd_integers-1)):
What is this supposed to do if n=1 and therefore all_odd_integers-1 = 2?
The code under this loop is never executed.
EDIT:
To loop over odd integers just do this:
for i in xrange(1,1000,2):

Related

How to skip a part of the code if a certain condition is met [duplicate]

This question already has answers here:
how to stop a for loop
(9 answers)
Closed 2 years ago.
As I am getting more and more comfortable with writing scripts in Python I wrote a script that finds prime numbers by trying to divide each number in a range in each number (kinda like Brute Force haha).
It works but I wanted to make the process faster and more efficient.
My code:
count = 0
for i in range(2,1000):
j = 2
while j < 1000:
if i%j==0:
count = count + 1
j = j + 1
if count == 1:
print(i)
count = 0
Explanation:
I check and store in count how many time does a number can be divided.
If by the end of the check count equals 1 that means that the number is prime (gets divided only by itself).
What I want now is to stop the process of checking how many times the number can get divided when the "count" variable exceed 1 (2 or more). How do I do that?
I wanted to do something with try and except but didn't know what...
Add an extra condition in here, and break out of the loop if the count is greater than one. Put this inside the while loop:
if i % j == 0:
count += 1
if count > 1:
break
As mentioned in the comments, it's cleaner to just use count as part of the loop condition. Here's an improved version:
for i in range(2, 1000):
j = 2
count = 0
while j <= i and count < 2:
if i % j == 0:
count += 1
j += 1
if count == 1:
print(i)
Of course, there are faster ways to find if a number is prime - in particular, in the inner loop you should not iterate until 1000, not even until i is reached, just until the sqrt(i), but I'll leave that as an improvement for you to make ;)
You can try using break. What break does is that it skips the remaining part of the loop and jumps to the statement following the loop.
count = 0
for i in range(2,1000):
j = 2
while j < 1000:
if i%j==0:
count = count + 1
break
j = j + 1 ### line 8
if count == 1:
print(i)
count = 0
In this code, when python encounters break, it skips the remaining part of the loop (that is, the remaining loop is not executed) and jumps straight to the next statement, which is line 8
Its all wrong, first you have to understand the algorithm to check for prime, basically a number is prime if it can't be fully divided by any number between 2 to (number//2)-1
Now in your question, you couldn't use break anywhere, bcz you first searching for all divisible and then checking prime, better I'm adding a sample code to your problem which is more feasible to find primes
Code
number = int(input("Enter A Number"))
for i in range(2,number//2+1): #See range arguments
if(number%i==0):
print("Not A Prime")
break #Break loop when condition reached

Prime checker including non primes

I am trying to solve Project Euler number 7.
By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13.
What is the 10 001st prime number?
First thing that came into my mind was using length of list. This was very ineffective solution as it took over a minute. This is the used code.
def ch7():
primes = []
x = 2
while len(primes) != 10001:
for i in range(2, x):
if x % i == 0:
break
else:
primes.append(x)
x += 1
print(primes[-1])
ch7()
# Output is: 104743.
This works well but I wanted to reach faster solution. Therefore I did a bit of research and found out that in order to know if a number is a prime, we need to test whether it is divisible by any number up to its square root e.g. in order to know if 100 is a prime we dont need to divide it by every number up to 100, but only up to 10.
When I implemented this finding weird thing happened. The algorithm included some non primes. To be exact 66 of them. This is the adjusted code:
import math
primes = []
def ch7():
x = 2
while len(primes) != 10001:
for i in range(2, math.ceil(math.sqrt(x))):
if x % i == 0:
break
else:
primes.append(x)
x += 1
print(primes[-1])
ch7()
# Output is 104009
This solution takes under a second but it includes some non primes. I used math.ceil() in order to get int instead of float but I figured it should not be a problem since it still tests by every int up to square root of x.
Thank you for any suggestions.
Your solution generates a list of primes, but doens't use that list for anything but extracting the last element. We can toss that list, and cut the time of the code in half by treating 2 as a special case, and only testing odd numbers:
def ch7(limit=10001): # assume limit is >= 1
prime = 2
number = 3
count = 1
while count < limit:
for divisor in range(3, int(number ** 0.5) + 1, 2):
if number % divisor == 0:
break
else: # no break
prime = number
count += 1
number += 2
return prime
print(ch7())
But if you're going to collect a list of primes, you can use that list to get even more speed out of the program (about 10% for the test limits in use) by using those primes as divisors instead of odd numbers:
def ch7(limit=10001): # assume limit is >= 1
primes = [2]
number = 3
while len(primes) < limit:
for prime in primes:
if prime * prime > number: # look no further
primes.append(number)
break
if number % prime == 0: # composite
break
else: # may never be needed but prime gaps can be arbitrarily large
primes.append(number)
number += 2
return primes[-1]
print(ch7())
BTW, your second solution, even with the + 1 fix you mention in the comments, comes up with one prime beyond the correct answer. This is due to the way your code (mis)handles the prime 2.

Finding primes in python

I know that python is "slow as dirt", but i would like to make a fast and efficient program that finds primes. This is what i have:
num = 5 #Start at five, 2 and 3 are printed manually and 4 is a multiple of 2
print("2")
print("3")
def isPrime(n):
#It uses the fact that a prime (except 2 and 3) is of form 6k - 1 or 6k + 1 and looks only at divisors of this form.
i = 5
w = 2
while (i * i <= n): #You only need to check up too the square root of n
if (n % i == 0): #If n is divisable by i, it is not a prime
return False
i += w
w = 6 - w
return True #If it isnĀ“t ruled out by now, it is a prime
while True:
if ((num % 2 != 0) and (num % 3 != 0)): #save time, only run the function of numbers that are not multiples of 2 or 3
if (isPrime(num) == True):
print(num) #print the now proved prime out to the screen
num += 2 #You only need to check odd numbers
Now comes my questions:
-Does this print out ALL prime numbers?
-Does this print out any numbers that aren't primes?
-Are there more efficient ways(there probably are)?
-How far will this go(limitations of python), and are there any ways to increase upper limit?
Using python 2.7.12
Does this print out ALL prime numbers?
There are infinitely many primes, as demonstrated by Euclid around 300 BC. So the answer to that question is most likely no.
Does this print out any numbers that aren't primes?
By the looks of it, it doesn't. However, to be sure; why not write a unit test?
Are there more efficient ways(there probably are)? -How far will this go(limitations of python), and are there any ways to increase upper limit?
See Fastest way to list all primes below N or Finding the 10001st prime - how to optimize?
Checking for num % 2 != 0 even though you increment by 2 each time seems pointless.
I have found that this algorithm is faster:
primes=[]
n=3
print("2")
while True:
is_prime=True
for prime in primes:
if n % prime ==0:
is_prime=False
break
if prime*prime>n:
break
if is_prime:
primes.append(n)
print (n)
n+=2
This is very simple. The function below returns True if num is a prime, otherwise False. Here, if we find a factor, other than 1 and itself, then we early stop the iterations because the number is not a prime.
def is_this_a_prime(num):
if num < 2 : return False # primes must be greater than 1
for i in range(2,num): # for all integers between 2 and num
if(num % i == 0): # search if num has a factor other than 1 and itself
return False # if it does break, no need to search further, return False
return True # if it doesn't we reached that point, so num is a prime, return True
I tried to optimize the code a bit, and this is what I've done.Instead of running the loop for n or n/2 times, I've done it using a conditional statements.(I think it's a bit faster)
def prime(num1, num2):
import math
def_ = [2,3,5,7,11]
result = []
for i in range(num1, num2):
if i%2!=0 and i%3!=0 and i%5!=0 and i%7!=0 and i%11!=0:
x = str(math.sqrt(i)).split('.')
if int(x[1][0]) > 0:
result.append(i)
else:
continue
return def_+result if num1 < 12 else result

Python "OverflowError" [duplicate]

This question already has answers here:
`xrange(2**100)` -> OverflowError: long int too large to convert to int
(5 answers)
Closed 13 days ago.
I am just starting to learn to code in Python. I am trying to write some code to answer this Project Euler Question:
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
My program works with the test case of 13195, but when I try to enter 600851475143, I get the error: "OverflowError: range() results has too many items"
Does anyone know how I can fix this?
Here is my code:
class Euler3:
"A class to find the largest prime factor of a given number"
n = 600851475143
primeFactors = []
for i in range(2,n):
if (n%i ==0):
primeFactors.append(i)
n = n/i
i = i -1 #reset i
print primeFactors
Any help or suggestions would be much appreciated!
The range function creates a list and tries to store it in memory. Creating a list many numbers long is what's causing the OverflowError. You can use xrange instead to get a generator which produces the numbers on demand.
That said, I think you'll find that your algorithm is way too slow for calculating large primes. There are a lot of prime number algorithms, but I might suggest checking out the Sieve of Eratosthenes as a starting point.
EDIT: Properly xrange actually doesn't return a generator, but an xrange object which behaves a lot like a generator. I'm not sure if you care, but it was bugging me that i wasn't precise!
I'm guessing you're using python 2 and not python 3 -- range(2,n) actually constructs a list! You don't have enough memory to store 600 billion numbers! xrange should be fine, though.
Also, your idea of i=i-1 doesn't work. For loops don't work like C, and that hack only works in C-style loops. The for loop iterates over range(2,n). If i gets the value 5 at once iteration, then no matter what you do to i, it still gets 6 the next time through.
Also, the list range(2,n) is constructed when you enter the loop. So when you modify n, that doesn't change anything.
You're going to have to rethink your logic a bit.
(if you don't believe me, try using 175 as a test case)
As a last comment, you should probably get in the habit of using the special integer division: n = n // i. Although / and // work the same in python 2, that is really deprecated behavior, and they don't work the same in python 3, where / will give you a floating point number.
You can fix the problem by using xrange instead of range
Your next problem will be that the program takes way too long to run because you need to break out of the loop under some condition
A better way to deal with repeat factors is to replace the if with a while
while (n%i ==0):
primeFactors.append(i)
n = n/i
n = 600851475143
primeFactors = []
for i in range(2,n):
i think you can optimize the function by noticing that
for i in range(2,n):
you can replace
range(2,n)
by
range(2,int(sqrt(n))+2)
because, you can see wiki...
This is the best way to find primes that I've found so far:
def isprime(n):
#make sure n is a positive integer
n = abs(int(n))
#0 and 1 are not primes
if n < 2:
return False
#2 is the only even prime number
if n == 2:
return True
#all other even numbers are not primes
if not n & 1:
return False
#range starts with 3 and only needs to go up to the square root of n
#for all odd numbers
for x in range (3, int(n**0.5)+1, 2):
if n % x == 0:
return False
return True #if it makes it through all the catches, it is a prime
This took me about 5 secs to get the answer.
import math
def is_prime_number(x):
for i in range(int(math.sqrt(x)), 2, -1):
if x % i == 0:
return False
return True
def next_prime_number(number):
#Returns the next prime number.
if number % 2 == 0 and number != 2:
number += 1
while not is_prime_number(number):
number += 2
return number
num = 600851475143
i = 2
while (i < long(math.sqrt(num) / 2)):
if num % i == 0:
largest = i
print largest
i = next_prime_number(i + 1)
xrange won't probably help you(or it may!),but the key thing here is to reliaze that you don't need to find the prime numbers up till 600851475143 or the factors of 600851475143,but it's prime factors,so...
Use the good old prime factorization method ,like so:
A=600851475143
n=2
fac=[]
while(n<=int(A)):
B=1
while(A%n==0):
B=0
A=A/n
if(B==0):
fac.append(n)
n=n+1
print max(fac)
This will return the argest prime factor almost instantly
I was battling with this Python "OverflowError", as well, working on this project. It was driving me nuts trying to come up with a combination that worked.
However, I did discover a clever, at least I think so :), way to do it.
Here is my code for this problem.
def IsNumberPrime(n):
bounds = int(math.sqrt(n))
for number in xrange(2,bounds+2):
if n % number == 0:
return False
return True
def GetListOfPrimeFactors(n):
primes = []
factors = GetListOfFactors(n)
if n % 2 == 0:
primes.append(2)
for entries in factors:
if IsNumberPrime(entries):
primes.append(entries)
return primes
GetListOfPrimeFactors(600851475143)
def GetListOfFactors(n):
factors = []
bounds = int(math.sqrt(n))
startNo = 2
while startNo <= bounds:
if n % startNo == 0:
factors.append(startNo)
startNo += 1
return factors
What I did was take the factors of the number entered and enter them into a list "factors". After that, I take the list of factors and determine which ones are primes and store them into a list, which is printed.
I hope this helps
-- Mike

Python prime number list wrong?

I've tried with several different methods to get the 10001 prime number.
def isPrime(value):
if ((2**value)-2)%value==0:
return True
def nthPrime(n):
count = 0
value = 1
while count < n:
value += 1
if isPrime(value):
count += 1
return value
When 10001 is the argument this returns 103903. When I'm expecting 104743.
I've tried:
primes = []
for i in range(2,105000):
if ((2**i) - 2) % i == 0:
primes.append(i)
print primes[10001] ---> 103903
I believe your prime sieve is wrong. Try using an isPrime function that takes that number mod each lesser prime. If any of these are 0 then the number is composite (not prime). To the best of my knowledge there is no single comparison that will tell you if a number is prime, as your isPrime function assumes.
Is this for Project Euler? It does seem familiar to me.
Your isPrime function is wrong, like TEOUltimus said, there is no one way to tell if a number is prime.
Simple Prime Generator in Python
This pretty much answers your question i guess.
You can make a function to generate primes, this might be slow but it will work.
Here's my function to do so :
def PrimesSieve(limit):
np=set()
p=[2]
for i in xrange(1,limit+1,2):
if i == 1: continue
if {i} & np: continue
beg=2 if i % 2 == 0 else 0
for j in xrange(beg,int(limit)+1,i):
np.add(j)
p.append(i)
return p

Categories

Resources