def bhl(x):
if x == 1:
return False
elif x == 2:
return True
elif x % 2 == 0:
return False
for b in range(3,int(x**0.5 +1)):
if x % b == 0:
return False
else:
return True
Don't know if I'm too tired but I really can't figure out what this part of the code does. Can someone please explain it for me:
elif x % 2 == 0:
return False
for b in range(3,int(x**0.5 +1)):
if x % b == 0:
return False
else:
return True
It checks whether x is prime
x % 2 == 0 checks if x is even, or in other words it has no remainder when you divide it by 2
for b in range(3,int(x**0.5 +1)): if x % b == 0: return False
This checks from 3 to x/2+1 if there is a number that divides x without remainder.
Previous cases checked 1 and 2, and there is no point in checking whether a number bigger than x/2 divides x without remainder, because there isn't one.
Related
I have a problem with my code that my teacher ask my to check the prime numbers but he does not allow me to use If-Else function . Here is my code:
def is_prime(n):
i = 2
while (i % n != 0):
while (n % i == 0) and ( n != i):
print("False")
break
i += 1
while (i == n):
print("True")
break
number = int(input("Please enter a certain number: "))
print(is_prime(number))
But the problem is when i print out the result, it's a little bit weird with the numbers which are not a prime number:
Please enter a certain number: 10
False
False
True
None
How would i solve this problem? I just need one answer: True or False. Thank you for your helps!!!
To be short: let your function to return a value, not to print it.
def is_prime(n):
i = 2
while (i % n != 0):
while (n % i == 0) and ( n != i):
return False
i += 1
return True
number = int(input("Please enter a certain number: "))
print(is_prime(number))
Explanation:
As soon as you find out that n is not prime (line while (n % i == 0) and ( n != i):) you return False. The function is left at this moment so you do not need break. If n is not found to be divisible by any i you return True.
The True or False is now the result of the function and you can print it or assign to a variable and use somewhere else. E.g.
x = is_prime(12) // x is False now
import math
def is_prime(num):
if num < 2:
return False
for i in range(2, int(math.sqrt(num))+ 1):
if num % i == 0:
return False
return True
Primes seems to be a popular topic but in the book in which I am learning Python, I am on chpt 6 out of 21 and in the iteration chapter which it teaches while loops. I have not learned for loops yet although I understand what they do. So, let's say I have not learned for loops yet and am given only if/elif/else statements and the while loops as my tools. How can I change the for line of code into something more simple using the above tools? While asking this question I quickly came up with this code:
def formula(num):
i = 2
while i >= 2:
return int(math.sqrt(num)+ 1)
def is_primetwo(num):
i = 2
if num < 2:
return False
formula(num)
if num % i == 0:
return False
return True
It works but would this be a simple version of the for loop or is there something even more simple where I do not have to wrap a function within a function?
Absolutely, you do not need a function to replace a for loop.
So you've got this
for i in range(2, int(math.sqrt(num))+ 1):
which is your for loop. Take a second to think what it's doing.
1.) It's taking the variable i, and it's starting it at a value of 2.
2.) It's checking whether to do the loop every time by checking if i is less than the (square root of num) plus 1
3.) Every time through the loop, it adds one to i.
We can do all of these things using a while loop.
Here's the original
for i in range(2, int(math.sqrt(num))+ 1):
if num % i == 0:
return False
let's rename the second and third lines loop contents just so we're focusing on the looping part, not what logic we're doing with the variables i and num.
for i in range(2, int(math.sqrt(num))+ 1):
loop contents
ok, now let's just rearrange it to be a while loop. We need to set i to 2 first.
i = 2
Now we want to check that i is in the range we want
i = 2
while i <= int(math.sqrt(num) + 1):
loop contents
Now we're almost set, we just need to make i actually change, instead of staying at a value of 2 forever.
i = 2
while i <= int(math.sqrt(num) + 1):
loop contents
i = i + 1
Your example seemed to do some of these elements, but this way is a simple way to do it, and no extra function is necessary. It could be the range() function that is confusing. Just remember, the for loop is doing three things; setting a variable to an initial value, checking a condition (one variable is less than another), and incrementing your variable to be one large than previously to run the loop again.
How about something like:
from math import sqrt
def is_prime(num):
if (num < 2):
return False
i = 2
limit = int(sqrt(num) + 1)
while (i <= limit):
if num % i == 0:
return False
i = i + 1
return True
Not sure if this is what you want, but the for loop:
for i in range(2, int(math.sqrt(num))+ 1):
if num % i == 0:
return False
return True
can be expressed as:
i = 2
while i < int(math.sqrt(num))+ 1):
if num % i == 0:
return False
i += 1
return True
Probably a good idea to determine int(math.sqrt(num))+ 1) once:
i = 2
n = int(math.sqrt(num))+ 1)
while i < n:
if num % i == 0:
return False
i += 1
return True
I wrote this python code to find any prime number, the 1st, 2nd, 1000th, etc. I ran the code and it returned this, no matter what integer I entered:
2 is the 1 prime
3 is the 2 prime
5 is the 3 prime
7 is the 4 prime
Here is the code (written in python 2.7.8):
#code to find the nth prime
def isprime(n):
'''check if integer n is a prime'''
# 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:
return False
# range starts with 3 and only needs to go up the squareroot 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
num_ofprimes = 0
candidate_prime = 2
final_primes = raw_input("What prime would you like to find?")
while num_ofprimes <= final_primes:
if isprime(candidate_prime) == True:
if candidate_prime == 2:
num_ofprimes = num_ofprimes + 1
print (str(candidate_prime) + " is the " + str(num_ofprimes) + " prime")
candidate_prime = candidate_prime + 1
#2 is prime
elif candidate_prime % 2 == 0:
candidate_prime = candidate_prime + 1
#if a number is even it is not prime
else:
num_ofprimes = num_ofprimes + 1
print (str(candidate_prime) + " is the " + str(num_ofprimes) + " prime")
candidate_prime = candidate_prime + 1
# checks all odd numbers to see if prime then prints out if true
print ("All done!")
Your program does not stop after it found those first few primes, but it runs into an infinite loop, generating no more output. The reason for this is that if your isprime check fails, you never increment the candidate_prime variable!
Also, as noted in comments, you should compare num_ofprimes to int(final_primes); otherwise you are comparing an int to a str, which is much like comparing apples to oranges.
Finally, you should put the check whether the number is even inside your isprime function. Not only will this make your isprime function actually return correct results for even numbers, but it will also make your code a whole deal more compact, as you no longer need all those if/elif/else blocks below your if isprime check.
In addition to tobias's important comments, you seem to be doing a lot of extra work in your script for no reason. The while loop can be simplified to:
while num_ofprimes < final_primes:
if isprime(candidate_prime):
num_ofprimes = num_ofprimes + 1
print (str(candidate_prime) + " is the " + str(num_ofprimes) + " prime")
candidate_prime = candidate_prime + 1
for num in range(3, 1000):
if num > 1:
for i in range(2, num):
if (num % i) == 0:
break
else:
print(num)
I'm going back and tooling around with Project Euler questions to see if I can speed up my code, this is 003: finding the max prime factor of a really big number.
def is_prime(n):
'''check if n is prime'''
if n == 1: return 0
elif n == 2: return 1
elif n % 2 == 0: return 0
for i in range(3, int(n**0.5) +1, 2):
if n % i == 0:
return 0
else:
return 1
factor_list = []
the_number = 600851475143
for i in range(3, int(the_number**0.5) +1, 2):
if the_number % i == 0: factor_list.append(i)
print factor_list
for i in factor_list:
if is_prime(i) == False: factor_list.remove(i)
print factor_list
print max(factor_list)
The first print call prints: [71, 839, 1471, 6857, 59569, 104441, 486847]
So far, so good, printing the pre-n^0.5 factors of n.
The second print call prints: [71, 839, 1471, 6857, 104441]
Wait, how did 104441 slip through the is_prime function?
The third print call prints the incorrect answer, namely 104441. My question is how is 104441 slipping through?
I believe you have an issue with your for loop. When you use a for-each loop, you usually don't want to remove values because it ends up skipping over some. So I think what is happening is that 59569 gets removed, and then because you remove it, your next i value is 486847.
If you want a working solution, refer to steveha's code.
It's always tricky to try to modify a list while looping over it. It's better and safer to just build the list you need, rather than trying to pull out values you don't need.
This code works perfectly:
factor_list = [n for n in xrange(3, int(the_number**0.5) +1, 2) if the_number % n == 0]
print(factor_list)
prime_factors = [n for n in factor_list if is_prime(n)]
print(prime_factors)
answer = max(prime_factors)
print(answer)
Also, you should be returning False and True from is_prime(), not 0 and 1.
Assume the availability of a function is_prime. Assume a variable n has been associated with a positive integer. Write the statements needed to compute the sum of the first n prime numbers. The sum should be associated with the variable total.
Note: is_prime takes an integer as a parameter and returns True if and only if that integer is prime.
Well, I wrote is_prime function like this:
def is_prime(n):
n = abs(n)
i = 2
while i < n:
if n % i == 0:
return False
i += 1
return True
but it works except for n==0. How can I fix it to make it work for every integer?
I'm trying to find out answers for both how to write function to get the sum of first n prime numbers and how to modify my is_prime function, which should work for all possible input, not only positive numbers.
Your assignment is as follows.
Assume the availability of a function is_prime. Assume a variable n has been associated with a positive integer. Write the statements needed to compute the sum of the first n prime numbers. The sum should be associated with the variable total.
As NVRAM rightly points out in the comments (and nobody else appears to have picked up on), the question states "assume the availability of a function is_prime".
You don't have to write that function. What you do have to do is "write the statements needed to compute the sum of the first n prime numbers".
The pseudocode for that would be something like:
primes_left = n
curr_num = 2
curr_sum = 0
while primes_left > 0:
if is_prime(curr_num):
curr_sum = curr_sum + curr_num
primes_left = primes_left - 1
curr_num = curr_num + 1
print "Sum of first " + n + " primes is " + curr_sum
I think you'll find that, if you just implement that pseudocode in your language of choice, that'll be all you have to do.
If you are looking for an implementation of is_prime to test your assignment with, it doesn't really matter how efficient it is, since you'll only be testing a few small values anyway. You also don't have to worry about numbers less than two, given the constraints of the code that will be using it. Something like this is perfectly acceptable:
def is_prime(num):
if num < 2:
return false
if num == 2:
return true
divisor = 2
while divisor * divisor <= num:
if num % divisor == 0:
return false
divisor = divisor + 1
return true
In your problem statement it says that n is a positive integer. So assert(n>0) and ensure that your program outer-loop will never is_prime() with a negative value nor zero.
Your algorithm - trial division of every successive odd number (the 'odd' would be a major speed-up for you) - works, but is going to be very slow. Look at the prime sieve for inspiration.
Well, what happens when n is 0 or 1?
You have
i = 2
while i < n: #is 2 less than 0 (or 1?)
...
return True
If you want n of 0 or 1 to return False, then doesn't this suggest that you need to modify your conditional (or function itself) to account for these cases?
Why not just hardcode an answer for i = 0 or 1?
n = abs(n)
i = 2
if(n == 0 || n == 1)
return true //Or whatever you feel 0 or 1 should return.
while i < n:
if n % i == 0:
return False
i += 1
return True
And you could further improve the speed of your algorithm by omitting some numbers. This script only checks up to the square root of n as no composite number has factors greater than its square root if a number has one or more factors, one will be encountered before the square root of that number. When testing large numbers, this makes a pretty big difference.
n = abs(n)
i = 2
if(n == 0 || n == 1)
return true //Or whatever you feel 0 or 1 should return.
while i <= sqrt(n):
if n % i == 0:
return False
i += 1
return True
try this:
if(n==0)
return true
else
n = abs(n)
i = 2
while i < n:
if n % i == 0:
return False
i += 1
return True