Have some doubts in this python program (PRIME or NOT) - python

So, I wrote a code to find if a number is PRIME or NOT...
I wrote it in 2 different ways, they are almost same but I just had a doubt. So here it is:
1st code:
num = int(input("Enter the number: "))
lim = num//2 + 1
for i in range(2,lim):
if num % i == 0:
print("Prime!")
break
else:
print("Not Prime!")
2nd Code:
num = int(input("Enter the number: "))
for i in range(2,num):
if num % i == 0:
print("Prime!")
break
else:
print("Not Prime!")
The 1st code takes the input(num) and according to the input sets a limit(which is the half number + 1)
and then checks if the num is divisible by all the numbers in range (2 to lim)
The second one is same but instead of setting a limit it just checks all numbers lower than the input, which means it has to do a little more work...
Now both of these are almost same, the only difference is I saved a line in 2nd one and output efficiency is also better!
Which code would you want me to prefer/
also if this code has any problems, pointing them out would be helpful!
Thanks :)

Explanation
The most important piece of iteration, namely determining whether a number is prime or not, is to keep track of it. Without this process and in the OP's program, a variable is not used to handle this, meaning that he checks whether a number is or isn't prime every single time and concludes at that point. He also uses an else statement which is syntactically incorrect.
To prevent this, we can use a variable to keep track of this. Let's call it isprime. We need to assume that a number will always be a prime unless otherwise said. This can be achieved by setting isprime to default be True, and setting it to be False when we conclude that it is not a prime, because is has a divisor. Finally, we can check this variable at the end and determine whether that number is a prime or not, because it would be set to False if not, or left as True if it is.
Another observation made is that the limit for determining primes can be reduced down to sqrt(n). This is because we do not need to find every factor if it exists, just its lowest corresponding factor. Let's look at an example:
Factors of 24: 2, 3, 4, 6, 8, 12
We can stop checking for the factors right here:
2, 3, 4 | 6, 8, 12, 24
This is because if a number has a factor (such as greater than the square root), it will have a corresponding factor less than the square root. As a result, we can set our limit to be sqrt(n), just for peace of mind + a time complexity of O(sqrt(n)) v. O(n).
As an extra note, sqrt is not inbuilt into Python. You will have to import it from the math library using:
from math import sqrt
Final Code
# Setup
num = int(input("Enter the number: "))
lim = sqrt(num)
isprime = True
# Loop & check
for i in range(2,lim):
if num % i == 0:
isprime = False
break
# Results
if isprime:
print("Prime!")
else:
print("Not prime!")

The logic of the solution is wrong. You gave to switch the "Prime" and "Not Prime" tags. Like follows;
num = int(input("Enter the number: "))
lim = num//2 + 1
for i in range(2,lim):
if num % i == 0:
print("Not Prime!")
break
else:
print("Prime!")
The solution 1 is more efficient because you do not need to do extra
computation to check num//2 + 1. So it is preferable.

Related

Python, trying to sum prime numbers, why is '7' not getting appended?

I am trying to make a simple function to sum the prime numbers of a given input. I am wondering why '7' isn't coming up in my appended list of prime numberS:
def sum_primes(n):
empty = []
for i in range(2,n):
if n % i == 0:
empty.append(i)
print(empty)
sum_primes(10)
Your method for determining if numbers are prime is a bit off. Your function seems to determine if the input num n is prime but not sum all prime numbers to it.
You could make an isprime function and then loop over that for all numbers less than n to find all primes.
Actually your program have logical error. First you have to understand the prime number logic.
Step 1: We must iterate through each number up to the specified number in order to get the sum of prime numbers up to N.
Step 2: Next, we determine whether the given integer is a prime or not. If it is a prime number, we can add it and keep it in a temporary variable.
Step 3: Now that the outer loop has finished, we can print the temporary variable to obtain the total of primes.
sum = 0
for number in range(2, Last_number + 1):
i = 2
for i in range(2, number):
if (int(number % i) == 0):
i = number
break;
if i is not number:
sum = sum + number
print(sum)
def sum_primes(y):
sum = 0
# for each number in the range to the given number
for i in range(2, y):
# check each number in the sub range
for j in range(2, int(i/2)+1):
# and if its divisble by any number between
# 2 and i/2
if i % j == 0:
# then it is not a prime number
break
else:
# print current prime
print(i)
# add prime to grand total
sum += i
return sum
print(sum_primes(10))
I think you have some problems with the way you are checking if your number is prime or not. A much simpler way would be to use a library that does this for you. It takes less time, is usually a better implementation than you or I could come up with, and it takes fewer lines, therefore, looking cleaner.
I would recommend primePy. Its whole point is to work with prime numbers.
I don't have my computer with me atm so I can't make any sample code for you and test it. But something like this should work.
from primePy import primes
prime_list = primes.upto(n)
print(prime_list)
I believe that function returns a list of all prime numbers up to n. And if you wanted to get the sum of all of those numbers, you can go about whatever method you want to do that.
Afterward, slap it into a def and you should be good to go.
If it doesn't work let me know, and I will try to test and fix it when I am in front of a computer next.

Print prime numbers within an interval [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 11 months ago.
Improve this question
This code is running for the 1-10 interval but for interval 20-30 it is writing 21 and 27 and I am unable to understand what's wrong in the code. I don't want to know other code; I want to know what's wrong in my code.
start = int(input("Enter the first number of the interval")) #starting of interval
end = int(input("Enter the last number of the interval")). #end of interval
for i in range(start, end+1):
for x in range (2,end):
if (i == 0 or i==1):
break
elif (i % x != 0):
print(i)
break
else:
break
for x in range (2,end):
if (i == 0 or i==1):
break
elif (i % x != 0):
print(i)
break
else:
break
This part of code should
print a number if it's prime, otherwise break
but it doesn't.
Do you notice something strange in your code? I do, and it's the fact that in every case the inner for loop breaks after the first iteration, rethink this aspect of your code, and it will work fine.
First, I am not sure whether you want the period after the inputting for the end. Also, your code checks if i is not divisible by x, then print. So for example, your code checks if 21 is divisible by 2. It is not, so your code prints it out and breaks.
Introduction
Your code is effectively testing if a number is odd and if it is, it prints it out.
If start is 1 and end is any number greater than 1, your code is printing every odd number greater than 2 in the interval [1, end].
It is printing all odd numbers, but not all odd numbers are prime!
Dissecting your code
Let's consider the [1, 20] interval. Your code outputs every odd number greater than 2 in the interval [1, 20].
3, 5, 7, 9, 11, 13, 15, 17, 19.
2 is prime and is missing from this list. We can fix that by writing the following within the outer loop but above the inner loop:
if i == 2:
print(i)
Now the output is `
2, 3, 5, 7, 9, 11, 13, 15, 17, 19.
This is better but 9, 15 are not prime numbers.
The if statement with condition (i == 0 or i == 1) inside of your inner loop is not causing any problems. Let's simplify the inner loop by moving this just outside of the inner loop (just above) so that your code becomes
for i in range(start, end+1):
if (i == 0 or i == 1):
# 0 and 1 are not prime
continue
if (i == 2):
# 2 is prime
print(i)
for x in range (2,end):
if (i % x != 0):
print(i)
break
else:
break
All that remains as the potential culprit for your problems is the inner loop so let's focus on that.
Whenever i is even, in the first iteration of the inner loop, we
have x = 2. We know that if i is even that i % 2 is 0 and so i % x != 0 is False and so we move onto the else, in which case we
break out of the inner for loop. This is all fine because no even
integer greater than 2 is prime!
Whenever i is odd, in the first iteration of the inner loop, we
have x = 2. We know that if i is odd that i % 2 is NOT 0 and so
i % x != 0 is True and then we print i and then break out of
the for loop.
We never once have x = 3 or x = 4 and so on!
The above describes precisely what you code is doing, which is ignoring even integers and simply printing out every odd integer.
Solution that outputs what you want
It would help me if I knew what definition of a prime number you have and/or what algorithm you are trying to implement. But since I don't have this information, I can only suggest a solution.
In order to solve your problem, you need to clearly have in mind what a prime number is. There are many equivalent definitions of a prime number (see the Wikipedia prime number page for examples of definitions). I chose a definition that suggests a natural algorithm for finding prime numbers. Whatever definition of prime number you were given, it is possible to prove mathematically that it is equivalent to this (for some this is the first definition of a prime number that they see!):
An integer i is prime if and only if i > 1 AND for all k in {2, 3,
..., i - 1}, i % k != 0.
In words this says that an integer i is prime iff i is strictly greater than 1 and for all integers k from 2 up until i - 1, k does not divide i evenly.
Here it is
start = int(input("Enter Start: "))
end = int(input("Enter End: "))
print(f"\nPrime numbers between [{start}, {end}]:")
for i in range(start, end + 1):
if (i == 0 or i == 1):
# i is not prime
continue
if (i == 2):
# i is prime
print(i)
continue
for x in range(2, i):
if (i % x) == 0:
break
if (i % x) != 0:
print(i)
Example session:
Enter Start: 20
Enter End: 30
Prime numbers between [20, 30]:
23
29
The (i == 0 or i == 1) check should be placed outside the inner for loop. Otherwise, for all i greater than or equal to 2, for every iteration in the inner loop, you will be checking to see if it is less than 2 or not. You are doing this check too much.
We know that when i == 2 that i is prime.
For i > 2, we appeal to the definition of a prime number above.
The inner loop and the last statement applies the second part of the prime definition.

Validate if input number is prime

Trying to write a program that checks if a number is prime.
Wrote the below code, but do not understand why do I have an output of 2 lines:
num = int(input("Provide number to check if prime: "))
if num <=1:
print("Invalid choice, try again")
num = int(input("Provide number to check if prime: "))
for i in range(2,num):
if num% i ==0:
print("Number is not prime")
break
if num %i !=0:
print("Number is prime")
My output is :
Provide number to check if prime: 15
Number is prime
Number is not prime
The sympy.isprime() is a built-in function under the SymPy module and can be utilized for checking of possible prime numbers. It is a direct function and returns True if the number to be checked is prime and False if the number is not prime.
>>> import simpy
>>> sympy.isprime(8)
False
>>> sympy.isprime(11)
True
or else define a function like this
>>> def isPrime(k):
# 1 is not prime number
if k==1:
return False
# 2, 3 are prime
if k==2 or k==3:
return True
# even numbers are not prime
if k%2==0:
return False
# check all numbers till square root of the number ,
# if the division results in remainder 0
# (skip 2 since we dont want to divide by even numbers)
for i in range(3, int(k**0.5)+1, 2):
if k%i==0:
return False
return True
>>> print(isPrime(13))
True
>>> print(isPrime(18))
False
As the first thing, you should remember that 1 isn't a prime number by definition, even if it can't be divided by any other number:
if (num == 1):
print("The number is NOT prime")
else:
for i in range(2, num):
if (num%i == 0): # If the number has a divisor
print("The number is NOT prime")
break
else: # If the for loop ends without reaching any break
print("The number IS prime")
The else branch of a for loop is reached when the loop ends without reaching any break AND the loop executes at least one time.
To better understand my answer, I would suggest to read this.
The error with your solution is caused by the loop printing that the number is prime for each time num%i == 0, so taking num = 6:
6%4 != 0 # The number is prime
6%5 != 0 # The number is prime
As Rajarshi Ghosh suggested, you should know that while programming it's a good idea to use imported functions to do this simple operations, in order to avoid long operations for such a simple job.
If you don't want to use an imported function, I would suggest you to read this article where they explained 6 ways of finding if a number is prime without using functions made by others.
You have issues in output, not only for the case of 15, but also for cases smaller than 1. The following code should work. It has two improvements.
It prints the correct output for 15. The key is to move the else block to align with the for loop.
It prints the correct output for any number smaller than 1, which is not prime. The key is to use the while-break method to get user enter right number until it is bigger than 1.
num = int(input("Provide number to check if prime: "))
while num <=1: #you need to use while loop
print("Invalid choice, try again")
num = int(input("Provide number to check if prime: "))
if num > 1: #only evaluate number is prime or not if it is greater than 1
for i in range(2,num):
if num% i ==0:
print("Number is not prime")
break
else: #to move the `else` block to align with the `for` loop.
print("Number is prime")
break #add a break here
Output:
What is a while loop?
A while loop tests the input condition. Every time the loop finishes, the condition is reevaluated (only evaluate number is prime or not if it is greater than 1). As long as the the number entered is <=1, the loop keeps executing (keep asking users for input).
If you want to just check whether a number is prime or not just do the following:
num = int(input("Provide number to check if prime: "))
flagNotPrime = False
if num > 1:
for i in range(2, num):
if (num % i) == 0:
flagNotPrime = True
break
if flagNotPrime:
print("Number is not prime")
else:
print("Number is prime")
Firstly, numbers that are <= 1 are not prime numbers. Therefore, the above code only proceeds if the num is greater than 1.
Secondly, the code checks if num is exactly divisible by any number from 2 to num - 1. If there is a factor in that range, the number is not prime, so the flag is set to True and the loop is broken using break.
Lastly, outside the loop, if the flag is True then num is not prime.

Is there a way to remove elements of a range without creating an array/list of included/excluded values in a for loop? (Python)

I am using Python 3.9 and I have created a very simple program to identify whether or not a number is prime when given in integer input.
My code itself works, but it can be very slow even given large numbers
(50 million+). I am using a for loop to check if any numbers between 1
and the input(x) are evenly divisible by the input(x). I want to exclude all
even numbers and multiples of 5 from the range since no primes are even or end in 5.
Is there a way to explicitly remove all evens and multiples of 5 without creating an array of excluded/included values like I did?
Here is a snippet code and time of the program for reference:
#program with filtering out evens and multiples of 5
print("Is your number prime?? Well... let's check!")
#'x' can actually be any input but I am using 60000049 as a constant value for the sake of timing.
x=60000049
factorlist=[]
#Included_values is an array in which all elements are divided into 'x' after it excluded all evens and multiples of 5.
included_values=[]
for i in range (1,x+1):
if i%2!=0 or i%5!=0:
included_values.append(i)
for i in range(1,len(included_values)):
if x%included_values[i]==0:
factorlist.append(i)
if len(factorlist)>2:
print("Oh no! It appears like the number you have entered is not prime. Try again!")
print('The factors to your number are:',factorlist)
if len(factorlist)<=2:
print('Yay! You have chosen a prime number!!')
Yay! You have chosen a prime number!!
~17.96522307395935
The first version of my program is much slower than the one that does not exclude any values:
#My program without filtering out evens or multiples of 5.
#'x' can actually be any number but I am using 60000049 for the sake of timing.
print("Is your number prime?? Well... let's check!")
x=60000049
factorlist=[]
for i in range (1,x+1):
if x%i==0:
factorlist.append(i)
if len(factorlist)>2:
print("Oh no! It appears like the number you have entered is not prime. Try again!")
print('The factors to your number are:',factorlist)
if len(factorlist)==2:
print('Yay! You have chosen a prime number!!')
Yay! You have chosen a prime number!!
~6.147368431091309
As you can see, my second program is much faster because it does not cycle through the range to get an array of excluded values first.
If there is a way to exclude even values and multiples of 5 first without cycling through the entire range (1,x+1), it would make my program much faster. If this is possible, let me know!
To answer your question, you could of course have an if inside the for to skip values. Well you already do, but using a list. I mean you could just have condition there.
Otherwise, a list comprehension is a more efficient way to create a new list than calling append in a loop like you do:
included_values = [i for i in range(1, x+1)
if i%2 !=0 or i%5 != 0]
I did that change in https://replit.com/#ToniAlatalo/DapperSeagreenMacro#main.py
Also the other for I think you could convert from:
for i in range(1,len(included_values)):
to:
for value in included_values:
Which might be a tiny bit faster but probably not much different.
If you want to exclude multiples of 2 or 5 only, you can try using list comprehension included_values = [k for k in range(1,x+1) if k%2!=0 and k%5!=0]
If you want your program to be "more efficient", I suggest checking to the square root of x only. included_values = [k for k in range(1, math.ceil(math.sqrt(x)))]
But, your code is not that efficient.
x = int(input("Is your number prime?? Well... let's check! Type your number here:" ))
from math import sqrt, ceil
if x ==2:
print('Your number is a prime')
elif x < 2:
print("Your number isn't prime")
else:
print('Your number is not prime' if any([k for k in range(2,ceil(sqrt(x))) if x%k==0]) else 'Your number is a prime')
Breakdown of code:
x = int(input("Is your number prime?? Well... let's check! Type your number here:" )) This will get your "x", but if x is predetermined, you can skip this.
from math import sqrt,ceil This will import sqrt and ceil from the math library
if x ==2:
print('Your number is a prime')
elif x < 2:
print("Your number isn't prime")
Check if number is smaller than 3, if it's 2, print the number is prime, else print that it's not prime
print('Your number is not prime' if any([k for k in range(1,ceil(sqrt(x))) if x%k==0]) else 'Your number is a prime') Check if any([k for k in range(2,ceil(sqrt(x))) if x%k==0]) is true, if it's true, number isn't a prime, but if it's false, number is a prime(Since x isn't divisible by any number in range of 2 to square root of x).
Granted, this is not perfect but will be fast enough for normal uses.
The i%2!=0 or i%5!=0 condition will only exclude multiples of 10 from your included_values list. Also, your next loop adds an index (instead of a factor) to the factorlist so it doesn't print the right factors even for the ones it does find (try it with x=15) it will also find that 10 is prime.
All this being said, if you want to list all the factors of the number (when it is not prime), you can't really skip any divisors.
To make it go faster, what you could do is check for factors up to the square root of x and add each divisor along with the resulting quotient for every match you find.
x = 60000049
factors = []
for f in range(1,int(x**0.5)+1):
if x%f == 0:
factors.extend({x//f,f})
print(factors) # [60000049, 1]
By skipping multiples of 2 and 5, appart from skipping factors and producing a wrong result, you'd only reduce the number of tests by 60% but stopping at the square root will eliminate 99.98% of them (for x=60000049).

Printing primes less than 100?

I am new to programming and trying to write a program that prints primes less than 100. When I run my program I get an output that has most of the prime numbers, but I also have even numbers and random odd numbers. Here is my code:
a=1
while a<100:
if a%2 == 0:
a+=1
else:
for i in range(2,int(a**.5)+1):
if a%i != 0:
print a
a+=1
else:
a+=1
The first part of my code is meant to eliminate all even numbers (doesn't seem to fully work). I also don't fully understand the part of my code (for i in).
What exactly does the "for i in" part of the code do? What is 'i'?
How can I modify my code that it does accurately find all of the primes from 1-100?
Thanks in advance.
See the comments on your post to find out why your code doesn't work. I'm just here to fix your code.
First of all, make use of functions. They make code so much more readable. In this case, a function to check if a number is a prime would be a good idea.
from math import sqrt
def is_prime(number):
return all(number%i for i in range(2, int(sqrt(number))+1))
There isn't much left to do now - all you need is to count how many primes you've found, and a number that keeps growing:
primes= 0
number= 1
while primes<100:
if is_prime(number):
print number
primes+= 1
number+= 1 # or += 2 for more speed.
Suddenly it's very easy to read and debug, is it not?
I'm going to try to guide you without giving you any code to help you learn, you should probably start from scratch I think and make sure you know how each part of your code works.
Some things about primes, 1 isn't prime and 2 is so you should start with a=3 and print 2 immediately if you want to eliminate even numbers.
By doing that, you will then be able to just increment a by 2 rather than 1 as you're doing now and just skip over even numbers.
As you loop a to be less than 100, you need to check if each value of a is prime by making another loop with another variable that loops downward through all numbers that could possibly divide a (less than or equal to a's square root). If that variable divides a, then exit the inner loop and increment a, but if it makes it all the way to 1, then a is prime and you should print it, then increment a.
There's several things wrong with what you're doing here:
You don't find the first 100 primes, you find the primes less than 100 with while a < 100
You print a every time a is evenly divisble by i, and then increment a. But you've gotten ahead of yourself! a is prime only if it is not divisble by any value i, but you fail to keep track of whether it's failed for any i.
You add +1 to the range up to the square root of the number - but that's not necessary. The square root of the number is the largest number that could possibly be the smaller of two factors. You don't need to add 1 because that number is _bigger than the sqare root - in other words, if a is evenly divisble by sqrt(a)+1 , then a / (sqrt(a)+1) will be smaller than sqrt(a)+1 and therfore would have already been found.
You never print the list of primes you found; you print a every time you find a number that is not a factor ( primes have no factors other than one and themselves, so you're not printing prime numbers at all!)
This might get you thinking in the right direction:
a=0
primes = []
while len(primes) < 100:
a = a + 1
prime=True
maxfactor = int(a ** .5)
for i in primes:
if i == 1:
continue
if i > maxfactor:
break
if a % i == 0:
print a, " is not prime because it is evenly divisble by ", i
prime=False
break
if prime:
print "Prime number: ", a
primes.append(a)
for p in primes:
print p

Categories

Resources