Trying to create a program that lists the prime numbers in a set interval (has to be between 1 and 500), so user input isnt allowed. This is my code so far:
list=[]
for num in range(1, 500):
if num > 1:
for i in range(2, num):
if (num % i) == 0:
break
else:
list.append(str(num))
print(','.join(list))
However, when I run this code some of the primes are repeated multiple times in the list, making it much longer than it should be. How can i fix this? Thanks in advance for any help.
You only want to add the number to the list of primes after you've checked all the possible divisors. That means you only add it after the for loop has completed.
A good way to do this is with the optional else clause on for loops.
Loop statements may have an else clause; it is executed when the loop
terminates through exhaustion of the list (with for) or when the
condition becomes false (with while), but not when the loop is
terminated by a break statement.
You can improve this function by only checking the modulus of primes you've already found. Since all non-prime numbers have prime roots, you only need to check if a number is divisible by lesser primes to determine if it is a prime.
primes = []
for i in range(2, 501):
for p in primes:
if i % p == 0:
break
else:
primes.append(i)
In the loop:
for i in range(2, num):
if (num % i) == 0:
break
else:
list.append(str(num))
you are appending the prime once for every i. The else should line up with the for:
for i in range(2, num):
if (num % i) == 0:
break
else: # note: different indentation!
list.append(str(num))
In python loops can have an else clause which is executed only if no break was executed inside the loop. They can be used to avoid boolean flags in a lot of cases.
So the code:
found = False
for x in iterator:
if predicate(x):
found = True
break
if not found:
# do default action
can be replaced by:
for x in iterator:
if predicate(x):
break
else:
#do default action
Make sure you are adding each only once.
The problem is that until you find a number i that divides num, num is added to the list. It is straightforward that you will have each prime in the list many times. In fact if n is prime, you will have n in the list n-2 times. You will also have all odd numbers in the list.
Only even numbers won't appear in the list, because the first number against which you are testing the divisibility is 2 and 2 divides all even numbers.
Without changing too much in your algorithm, you can introduce a flag isPrime that is set to True by default, and whenever you find i that divides num you set isPrime to True before breaking the loop. Your program becomes:
list=[]
for num in range(1, 500):
if num > 1:
isPrime=True
for i in range(2, num):
if (num % i) == 0:
isPrime = False
break
if isPrime:
list.append(str(num))
print(','.join(list))
Related
Hey so i have these two functions. The first one checks whether a number is a prime number which works. The second one is supposed to take a number and have all the prime numbers that are smaller than that number added into a sorted list. This is the code i have right now,
def is_prime(n):
flag = True
if n == 1:
flag = False
for i in range(2, n):
if (n % i) == 0:
flag = False
return flag
def primes(num):
primelist = []
flag = is_prime(num)
for i in range(1, num - 1):
if flag == True:
primelist.append(num)
return sorted(primelist)
How would i go about adding all the prime numbers lower than a integer into the list?
You've almost got it!
The issue in your primes function is that flag is computed outside of the loop. So it's computed only once for the input num.
Instead, it should be computed for every loop entry.
This code is meant to output prime numbers within a given range:
def sqrt(n):
return n**0.5
# find primes
def primes(minNum, maxNum):
primes_sum = 0
for i in range(minNum, maxNum):
current_max = int(sqrt(i))
for n in range(2, current_max + 1):
if(i%n == 0):
break
else:
primes_sum += i
print(i)
break
print('\nSum of all primes: ', primes_sum)
primes(10, 20)
However, I get an incorrect output:
11, 13, 15, 17, 19
Does someone know how the 15 manages to appear? I put print statements in the first if statement block to verify that 15 is detected by the if(i%n == 0) condition, and it is, but somehow it still appears in my final output and I can't figure out why.
I made changes to your code. Try in this way:
def sqrt(n):
return n**0.5
# find primes
def primes(minNum, maxNum):
primes_sum = 0
for i in range(minNum, maxNum):
current_max = int(sqrt(i))
#print(current_max)
flag = True
for n in range(2, current_max + 1):
#print(i,n)
if(i%n == 0):
flag = False
if flag:
print(i)
primes_sum += i
print('\nSum of all primes: ', primes_sum)
primes(10, 200)
In your code, you are not checking whether all the number is divisible by all the numbers. It will fail for all the odd non-prime numbers as it will check whether it is divisible by 2, if not it is a prime number
This logic:
for n in range(2, current_max + 1):
if(i%n == 0):
break
else:
primes_sum += i
print(i)
break
doesn't work to detect prime numbers, because if the first value of n you test (which will be 2) isn't a factor, you'll immediately count it as a prime and break the loop. You need to finish iterating over the entire range before deciding a number is a prime:
for n in range(2, current_max + 1):
if i % n == 0:
break
else:
primes_sum += i
print(i)
Note that the else is part of the for, not the if -- it only executes if the for loop exhausts itself without ever hitting a break (i.e. if it doesn't find any n values that are factors of i).
The reason is perfectly explained by #SAI SANTOSH CHIRAG. I won't copy that. I'm not sure why you're using sqrt of a number. You can do the stuff without sqrt. You would get wrong output if you use sqrt. In your case, if we check for sqrt of 18, then int of it would be 4 and the divisibility is checked from 2 to 4 whereas 18 is also divisible by 6. I am designing a new code without sqrt and explaining it as well.
My logic: define a function that takes upper bound and lower bound as parameter. Take a for loop ranging from lower bound to upper bound. Now each value will be a number between the range. We've to check whether the number is prime. Use loop ranging from 2 to number and check whether it is divisible or not. If yes, it is not prime. If no, add it to sum. Your code:
def primes(low,upp):
su=[]
for i in range(low,upp+1):
f=True
for j in range(2,i):
if i%j==0:
f=False
if f:
su.append(i)
return su,sum(su)
print(primes(10,20))
With this code, I only get to test if the number the user entered is prime or not.
How do I add another loop to my original code in order to find all the prime numbers less than or equal to the number the user has entered?
num = int(input("Enter a number: "))
if num > 1:
prime = True
for n in range(2, num):
if (num % n) == 0:
print ("Number", num, "is not prime")
break
else:
print("Number", num, "is prime")
You can'not print both in one loop, you can do one thing add a loop above your current loop and display each number like this :
num = int(input("Enter a number: "))
if num > 1:
prime = True
for n in range(2, num):
if (num % n) == 0:
print ("Number", num, "is not prime")
break
else:
print("Number", num, "is prime")
#your current code ends here
for j in range(2, num + 1):
# prime numbers are greater than 1
for i in range(2, j):
if (j % i) == 0:
break
else:
print(j)
Your code only check the number entered is prime or not , but you questioned about to get prime numbers from 2 to n (n = number entered by user) for this you run below code with the help of flag bit it will little bit easy for you. i hope it will help you.
Try This i run this code It will Surely help you to find your answer it work in python 3.0 or above
num = int(input("Enter The Number"))
if num > 1:
num = num+1
list = []
for j in range (2,num,1):
flag = 0
for i in range (2,int(j/2)+1,1):
if(j%i)== 0:
flag = 1
break
if flag==0:
list.append(j)
print(list)
else:
print("Enter Number Greater Than 1")
Aside from small things (unused boolean variable) your prime test is also super inefficient.
Let's go through this step by step.
First: To test if a number is prime, you don't need to check all integers up to the number for divisors. Actually, going up to sqrt(num) turns out to be sufficient. We can write a one-liner function to find out if a number is prime like so:
from numpy import sqrt
def is_prime(n):
return n > 1 and all(n%i for i in range(2,int(sqrt(n))+1))
range(2,some_num) gives an iterator through all numbers from 2 up to some_num-1and the all() function checks if the statement n%i is true everywhere in that iterator and returns a boolean. If you can guarantee to never pass even numbers you can start the range from 3 (of course with the loss of generality). Even if you don't want to use that function, it's cleaner to separate the functionality into a different function, because in a loop of numbers up to your input you will probably have to check each number for being prime separately anyways.
Second: From here, finding all primes smaller or equal than your input should be pretty easy.
num = int(input("Enter a number:"))
assert num>0, "Please provide a positive integer" # stops with an assertion error if num<=0
prime_lst = [2] if num > 1 else []
for x in range(3,num+1,2):
if is_prime(x):
prime_lst.append(x)
The list prime_lst will contain all your sought after prime numbers. I start the loop from 1 such that I can loop through only the odd numbers, even numbers are divisible by two. So this way none of the numbers will be divisible by two. Unfortunately this requires me to check if the number itself may be 2, which is a prime. By the twin-prime conjecture we can not simplify this range further without knowing about the input.
Finally: If you really want to find the primes in one loop, change your loop to something along the lines of:
prime_lst = [2] if num > 1 else []
for x in range(3,num+1,2): # outer loop
for i in range(3,int(sqrt(x))+1): # inner loop for check if x is prime
if x%i == 0:
break # breaks the inner loop, number is not prime
else:
prime_lst.append(x)
Edit: Just saw that the second answer here has a good explanation (and an even better way) of writing the one-liner for finding out if a number is prime.
def countPrimes(self, n):
if n <= 1:
return 0
if n == 2:
return 1
count = 0
counted = [2, ]
for num in xrange(3, n+1, 2):
for c in counted:
if num % c == 0:
continue
count += 1
counted.append(num)
return count
I am writing a code for the solution of primes counting problems. I used counted as an array storing for primes that have been examined and use them for the examination for the next prime. I tried using continue to drop out the inner for loop then count += 1 and counted.append(num) would not be executed once the num is found not a valid prime. However, I met implementing problem here, as the continue statement would take me to another c instead of another num.
If I understand your question correctly, you want to know how to break the inner c loop, avoid the other code, and continue with another num. Like the other answers, you want to make use of break with some smart booleans. Here's what the loop might look like:
for num in xrange(3, n+1, 2):
next_num = False
for c in counted:
if num % c == 0:
next_num = True
break
if next_num:
continue
count += 1
counted.append(num)
This way, if you encounter a num that is divisible by c, you break out of the inner c loop, avoid adding num to the counted list.
It doesn't make a ton of sense to accumulate a count and a list of primes as you go. Introduces the chance for a mismatch somewhere. I've massaged the code a bit, with some more descriptive variable names. It's amazing how clear names can really make the algorithm make more sense. (At least for me it does)
def primesUpTo(n):
primes = []
if n > 1:
primes.append(2)
for candidate in xrange(3, n+1, 2):
for prime in primes:
candidate_is_prime = candidate % prime
if not candidate_is_prime: # We're done with this inner loop
break
if candidate_is_prime:
primes.append(candidate)
return primes
print len(primesUpTo(100))
Try using break instead of continue. See the documentation here. Basically break takes you out of the smallest enclosing loop, spitting you back into your higher-level loop for its next iteration. On the other hand, continue just jumps you on to the next iteration of the smallest closing loop, so you wouldn't go out to the higher-level loop first.
I'm getting several incorrect answers in this code. For example, 9 is showing as prime. I'm guessing my problem is with using the breaks, but I can't seem to logically figure out what is wrong with this simple code someone asked me about.
for number in range(0, 1000):
for x in range(2, number):
if (number % x == 0):
break
else:
print x
break
In your script, regardless of if the number is divisble by 2 or not, it breaks the loop immediately.
I've reindented the code and this is probably closer to what you were trying to do.
In your original code, if the number is divisible by 2 (first number in the range(2,number), then you break the loop and if it is not divisible you also break the loop. So all odd numbers, like 9, looked like primes.
The else keyword after a for loop is run iff the loop exits normally. So the "is prime" part will only be printed if no divisor is found.
for number in range(0,1000):
for x in range(2,number):
if(number % x == 0):
print number,"divisible by",x
break
else:
print number, "is prime"
You can see this is anction here: http://codepad.org/XdS413LR
Also, this is a naive algorithm (not a critique of the code, exploring simple algorithms is a useful study), but you can make a little more efficient. Technically you only need to check as far as the sqare root of number, as any number larger than the square root must have a complement that is less than the square root, which should have already been encountered. So the logic in the code can be changed to:
from math import sqrt
for number in range(0,1000):
for x in range(2,int(sqrt(number/2))):
# Rest of code as above.
That said there are many ways that you can optimise the checking or discovery of prime numbers that are worth investigating if you get the chance.
I think you want something like this:
for number in xrange(100):
for i in range(2,number):
if number % i == 0:
break
else:
print number
this iterates through every number form 1-100 and checks if any number is divisible by any # besides one but you need the else: statement out side of the inner for loop so if it goes throught the inner for loop without finding a divisor its prime
Here are some alternatives. First, this checks for primes:
def check_for_prime(n):
if n == 1: return False
elif n == 2: return True
elif n%2 == 0: return False
# Elementary prime test borrowed from oeis.org/A000040.
odds = 3
while odds < n**.5+1:
if n%odds == 0: return False
odds += 2
return True
This is slightly faster, but you should have experience using yield:
def primes_plus():
yield 2
yield 3
i = 5
while True:
yield i
if i % 6 == 1:
i += 2
i += 2
Here are some alternatives.
n is the number till the range you want to find
n=100
for i in range(0,n):
num = filter(lambda y :i % y == 0,(y for y in range(2,(i/2))))
if num or i == 4:
print "%s not a prime number" %(i)
else:
print "%s is a prime number" %(i)