can I get the for loop to run the whole range? - python

This is my code. I am trying to find the prime numbers before or equal to the integer inputted. However, it seems that the loop stops when it sees an integer in the range that fits the requirements. Unfortunately, this is not I wanted it to do. I would like to make it run through all the tests in the range before making the judgement. Is this possible? If so, how do I do this? Thank you.
def getNumber(main):
n = int(input())
return n
def isPrime(n):
list=[2]
if n > 1:
for i in range(2, n+1):
for a in range (2, n):
if i*a != i and i%a != 0 and i%2 != 0:
list.append(i)
break
return "\n".join(map(str, list))`
def main():
n = getNumber(main)
print(isPrime(n))
main()

You've got your logic a bit wrong. Here's what your code is doing:
Examine numbers in increasing order from 2 to the inputted n.
For each number i, check if any number a between 2 and n divides i
If a divides i, add i to the list, and then move to the next i
This isn't going to get you a prime number. In fact, I'm having trouble figuring out what it will give you, but a prime number probably isn't it. Look at this function instead, which will return all the prime numbers less than or equal to the given number - you can compare it to your code to figure out where you went wrong:
def getPrimesLessThanOrEqualTo(n):
if n <= 1: # Anything 1 or less has no primes less than it.
return "" # So, return nothing.
list = [2] # 2 is the lowest prime number <= n
for i in range(3, n+1): # We start at 3 because there's no need to re-check 2
for a in list: # Instead of iterating through everything less than
# i, we can just see if i is divisible by any of
# the primes we've already found
if i % a == 0: # If one of the primes we've found divides i evenly...
break # then go ahead and try the next i
list.append(i) # Now, if we got through that last bit without
# hitting the break statement, we add i to our list
return "\n".join(list) # Finally, return our list of primes <= i
If you wanted to be more efficient, you could even use range(3, n+1, 2) to count by twos - thus avoiding looking at even numbers at all.

You can use a if/else block if your break is never executed by any item in the iterable the else statement will triggered. https://docs.python.org/3/tutorial/controlflow.html 4.4 demonstrates this accomplishing this almost exact task.
n = int(input('Enter number: '))
if n <= 1:
print('No primes')
else:
primes = []
for i in range(2, n +1):
for k in range(2, i):
if not i % k:
break
else:
primes.append(i)
print(*primes)
# Enter number: 50
# 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47

Related

Understanding the logic of this prime number generator output

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))

Python - My query to extract prime numbers does not work

I am attending a course on Udemy and one of the exercises is to return all the prime numbers from a range of numbers (for example all prime numbers before 100)
This is the query that the teacher made
def count_primes2(num):
#Check for 1 or 0
if num < 2:
return 0
######################
#2 or greater
#Store our prime numbers
primes = [2] #I start my list with 2 that is a prime number
#Counter going up to the input num
x = 3 #I create a variable on which I will continue adding until I reach num
# x is going through every number up to the input num
while x <= num:
#Check if x is prime
for y in range(3,x,2): # for y in range from 3 to x in even steps, we only wantto check odd numbers there
if x%y == 0:
x += 2
break
else:
primes.append(x)
x += 2
print(primes)
return len(primes)
count_primes2(100)
However, I came up with the one below that is not working. My idea is:
Given each number i between between 3 and num+1 (for example 100 would be 101 so that 100 can be included in the calculation):
Open a for loop in which I divide i by each number g before i (including i) and I have a counter checking when this division gives no remainder. This implies that in case of prime numbers the counter should always be 2 (for example 3--> 3:1 and 3:3 would give remainder 0).
If the counter is equal to 2, then i is a prime and I want to append it to the list.
I am not using any while loop in my query. Can you help me to identify why my query is not working?
def count_prime(num):
counter=0
list_prime=[2]
if num<2:
return 0
for i in range(3,num+1):
for g in range(1,i+1):
if i%g==0:
counter+=1
if counter==2:
list_prime.append(i)
return list_prime
count_prime(100)
Kudos to Khelwood for the help. Below the working query:
def count_prime(num):
counter=0
list_prime=[2]
if num<2:
return 0
for i in range(3,num+1):
for g in range(1,i+1):
if i%g==0:
counter+=1
if counter==2:
list_prime.append(i)
counter=0
return list_prime
count_prime(100)
you may do this :
for i in range(2,num):
if (num % i) == 0:`
Instead of using two for loops, you can simply eliminate one of the for loop and do this, I hope this may work for you.
thankyou.

Calculating the thousandth prime

The problem asks to calculate the 1000th prime number. I am trying to solve this problem but I am stuck.
There are some guidelines on how to solve the problem.
To help you get started, here is a rough outline of the stages you should probably follow in
writing your code:
Initialize some state variables
Generate all (odd) integers > 1 as candidates to be prime
For each candidate integer, test whether it is prime
One easy way to do this is to test whether any other integer > 1 evenly
divides the candidate with 0 remainder. To do this, you can use modular
arithmetic, for example, the expression a%b returns the remainder after
dividing the integer a by the integer b.
You might think about which integers you need to check as divisors –
certainly you don’t need to go beyond the candidate you are checking, buthow much sooner can you stop checking?
If the candidate is prime, print out some information so you know where you are
in the computation, and update the state variables
Stop when you reach some appropriate end condition. In formulating this
condition, don’t forget that your program did not generate the first prime (2).
Use these ideas to guide the creation of your code.
My attempt so far is this
def calculate_thousandth_prime():
j = 0
for i in range(3,int(10e6)):
if i%2 != 0:
counter = 0
for k in range(1, i):
if i%k != 0:
counter += 1
if counter == 0:
print("This candidate is prime")
j += 1
if j == 1001:
print("The number "+str(i)+" is the thousandth prime")
break
return 0
calculate_thousandth_prime()
My code gets stuck on i%k != 0. I must be doing something wrong... any help?
You have two problems:
First, you're searching for k in range(1, i):. Because every number, including primes, is divisible by 1, you won't find any primes. Try searching range(2, i) instead.
Second, you're checking if i%k != 0:. You should be checking that i%k == 0 instead. If i is divisible by any number k, then the number is not prime.
Actually, I found a third issue: You have an off-by-one error. By initializing j=0, your code considers the first prime it finds to be the "zeroth" prime. The code will output the thousand-and-first prime, instead of the thousandth prime.
Changes I made:
Change your range to add a 2 step to skip even numbers more naturally.
Check your inner loop, you need to divide by the values range(2, i//2). Dividing by anything greater than i//2 will be less than 2.
Change your prime check to see if any number in the above range divides. If so, we know the number is false. At that point we can move onto the next number.
We want to return when the prime counter is 1000, you were returning the 1001th prime.
def calculate_thousandth_prime():
prime_counter = 0
for i in range(3,int(10e6),2):
prime = True
for k in range(2, i//2):
if i % k == 0:
prime = False
break
if prime:
print(str(i) + " is prime")
prime_counter += 1
if prime_counter == 1000:
print("The number "+str(i)+" is the thousandth prime")
break
return i
calculate_thousandth_prime()
The sieve of Eratosthenes is generally the fastest way for the early primes. You can adapt it to reach the nth prime.
For example:
def nthPrime(N):
sieve = [1]*(N**2)
p = 2
for _ in range(N):
while not sieve[p]: p += 1
sieve[p::p] = [0]*len(sieve[p::p])
return p
nthPrime(100) # 541
The prime list divisor check method is probably easier to write and understand but it is much slower (although for only 1000 primes, this wouldn't make much of a difference):
def nthPrime(N):
primes = [2]
p = 1
while len(primes)<N:
p += 2
primes += [p]*all(p%d for d in primes)
return p

Find prime numbers less than or equal to the number the user has entered with loops. How do I do that?

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.

Finding a prime number

The problem is that you need to find the prime number after the number input, or if the number input is prime, return that. It works fine. It's just not working when the input is print(brute_prime(1000)). It returns 1001 not 1009. The full code is this:
def brute_prime(n):
for i in range(2, int(n**(0.5))):
if n % i == 0:
n += 1
else:
return n
As Barmar suggests, you need to restart the loop each time you increment n. Your range also ends earlier than it should, as a range stops just before the second argument.
def brute_prime(n):
while True:
for i in range(2, int(n**(0.5)) + 1):
if n % i == 0:
break
else:
return n
n = n+1
remember 2 is a prime number. again you can just check the division by 2 and skip all the even number division
def brute_prime(n):
while True:
if n==2:return n
elif n%2 ==0 or any(n % i==0 for i in range(3, int(n**(0.5)+1),2)):
n += 1
else:
return n
You're not restarting the for i loop when you discover that a number is not prime and go to the next number. This has two problems: you don't check whether the next number is a multiple of any of the factors that you checked earlier, and you also don't increase the end of the range to int(n ** 0.5) with the new value of n.
def brute_prime(n):
while true:
prime = true
for i in range(2, int(n ** 0.5)+1):
if n % i == 0:
prime = false
break
if prime:
return n
n += 1
break will exit the for loop, and while true: will restart it after n has been incremented.
as mention by Chris Martin the wise solution is define a isPrime function separately and use it to get your desire number.
for example like this
def isPrime(n):
#put here your favorite primality test
from itertools import count
def nextPrime(n):
if isPrime(n):
return n
n += 1 if n%2==0 else 2
for x in count(n,2):
if isPrime(x):
return x
if the given number is not prime, with n += 1 if n%2==0 else 2 it move to the next odd number and with count check every odd number from that point forward.
for isPrime trial division is fine for small numbers, but if you want to use it with bigger numbers I recommend the Miller-Rabin test (deterministic version) or the Baille-PSW test. You can find a python implementation of both version of the Miller test here: http://rosettacode.org/wiki/Miller%E2%80%93Rabin_primality_test#Python

Categories