removing "none" result from the function which prints the prime number - python

i wanna write a function that if the number is prime the function gives it as a result,but for non prime numbers i get a None,here is my code:
def isprime(n):
a=0
if n==1:
a=1
if n==2:
a=1
for i in range(2,n):
if n%i==0:
a=0
break
else:
a=1
break
if a==1:
return n
if a==0:
return
print(isprime(68))
the result for 68 is None

If you don't want to print None when you get that returned from your function, you need to change the printing code, rather than the function's code. Use something like:
p = isprime(x)
if p is not None:
print(p)
But your isprime function isn't actually working properly anyway. It will always return None for any value other than 2 or 3.
This is because the for loop will run only a single iteration, because you always hit a break statement in the if or else block it contains. You don't want to break if the number you tested is not a divisor. In fact, you don't need to do anything in that case.
Just use:
for i in range(2,n):
if n%i==0:
a=0
break
with no else block.
Note that you could simplify it a bit by using a return in the if block rather than setting a flag variable (which should really be given a more meaningful name than a if you do intend to keep it).
Here's a streamlined version of the same algorithm. I've added a few improvements, such as stopping the range after int(sqrt(n)), and iterating only on odd values (since 2 is handled by a special case at the beginning). I'm also explicitly naming None as the return value, to make it clear that it is intentional to return that value when n is a composite (a bare return makes it seem like the None is supposed to be ignored):
def isprime(n):
if n==1:
return None
if n==2:
return 2
for i in range(3,int(math.sqrt(n))+1,2):
if n%i==0:
return None
return n

In the case of not a prime number (a=0) you return nothing:
if a==0:
return
and if you print the value of a function which returns nothing, it prints None.
To solve this, return a number, or in this case a boolean would be more logical. So instead of setting a=0 or a=1 you can use a=False and a=True. Then you can do return a.

It is usually good practice in methods that require you to print something out to have a "base-case" because you should never get a none-type because you will always be returning something back to the print/calling function.
a=0
if n==1:
a=1
if n==2:
a=1
for i in range(2,n):
if n%i==0:
a=0
break
else:
a=1
break
if a==1:
return n
# By having a base case return statement we will
# never print out a none type, even upon error.
return (n + 'is not prime')

Related

Why is my prime number checking code not displaying the correct output?

I have a code that checks whether a number is prime or not, and outputs "Yes" or "No" accordingly. But when I input 1763, it outputs "Yes" even though it isn't a prime. The code checks whether a number is prime or not by checking if it can be divisible by any number between 2 and n-1. So when I input 1763, it should output "No" because 1763 can be divisible by 41. What went wrong in my code?
def getNumber():
n=int(input())
return n
def isPrime(n):
if n==2:
print("Yes")
else:
for i in range (2,n):
if n%i==0:
print("No")
break
else:
print("Yes")
break
def main():
n = getNumber()
isPrime(n)
main()
The problem is that you are not accounting for all the divisors. As soon as your first condition (if n%i==0:) is false, you execute the second elif condition and print "Yes".
Solution: You can use a flag which will be turned 1 only when a divisor will be found, which means the number is not prime. Below is slightly modified code of yours (showing only partial code, rest remains the same as yours). As pointed out by #bereal in the comments, you don't need to iterate up to n but only up to the square root sqrt(n). math.ceil returns the closest rounded off integer.
import math
def isPrime(n):
flag = 0
if n==2:
print("Yes")
return
else:
# for i in range (2, n):
for i in range (2, math.ceil(np.sqrt(n)) + 1):
if n%i==0:
print("No")
flag = 1
break
if not flag:
print ("Yes")
1763
No
In your loop you break on the first iteration, even if you haven't been able to prove that it isn't a prime yet.
You need to print yes only after you've checked all possible divisors up to n (it's actually enough to only check all numbers upp to the square of n).
for i in range (2,n):
if n%i==0:
print("No")
return
print("Yes")
You should declare a number to be a prime only after you iterate through all the possible divisors without finding one. For that you can use the for-else construct instead, where the else block is only executed if the for loop isn't aborted with a break statement:
def isPrime(n):
if n==2:
print("Yes")
else:
for i in range (2,n):
if n%i==0:
print("No")
break
else:
print("Yes")

For loop_python

I don't know why such an easy syntax result in mistake. Can anyone help me to see if I missed out any?
This part only tries to check if a particular (num) is prime or not.
Not sure why my check_primes(10) results into 'PRIME'. Cuz I'm looping through y from 3,4,5,6,...,9-> then 10%5==0, I suppose it returns true and 'Non PRIME' is the result.
Do I do any wrong in my loop?
def check_primes(num):
for y in range(3,num):
if num%y==0:
return 'Non PRIME'
else:
return 'PRIME'
A way to return 'PRIME' or 'Non PRIME' as in your example:
def check_primes(num):
is_prime = True
for y in range(3,num):
if num % y==0:
return 'Non PRIME'
else:
continue
return 'PRIME'
You will return 'Non PRIME' the moment you can verify the number is not prime. Alternatively if you succeed in all your checks, you will return 'PRIME' as desired.
(Note that this is not a very efficient way to get primes)
(Note also that the comment below is correct, this method works exactly the same way with or without the else clause)
The definition of "prime" states that a number is prime if and only if it is only divisible by 1 and itself. This means that a number is not prime if you find one number from 2 to n-1 which divides n. To check that a number is prime, you must check every number from 2 to n-1. Your code stops immediately after testing divisibility by 3 in both cases.
You should use print instead of return. You are breaking your loop when you return it.

For loop in Python somehow exits early

I am really sorry for the vague title but I don't really know the specifics of what's happening with my code. I am currently learning Python and finding it interesting so far. I am practicing the concept of generator functions and wrote a little program that finds palindromes using a generator function.
Here is the code (Python 3.6, written in Spyder):
def ispalindrome(n):
#creates a list for storing the element of the number one by one
l=[]
#storing the digits
while n!=0:
l.append(n%10)
n=int(n/10)
#setting useful variables
i=len(l)-1
flag=False
#traversing the list and checking whether palindrome
for n in range(0,len(l)):
#this block is executed only if n is less than (len(l)-1)-n
if n<i-n:
#comparing elements
if l[n]==l[i-n]:
#flag is set to true everytime l[n] equals l[(len(l)-1)-n]
flag=True
else:
break
#if n>(len(l)-1)-n
else:
break
#returns the flag
return flag
#basic generator function that yields whenever ispalindrome() returns true
def palindromes(n=1111):
while True:
if ispalindrome(n): yield n
n+=1
#traversing through palindromes generator function
for n in palindromes():
if n>1131: break
print('{} is a palindrome'.format(n))
When ran I get this output:
1111 is a palindrome
1121 is a palindrome
1131 is a palindrome
Needless to say the output is completely wrong. I added a few prints in my code and tried to find out the issue and it looks like the program is exiting the for loop inside ispalindrome() function early. It is exiting the for-loop as soon as it encounters two digits and two ends which match, when this should not be the case. Is it because of the break keyword somehow?
I will greatly appreciate if someone can point out what am I doing wrong with this code and how should I approach this correct the issue. Thanks in advance!
I think your problem is that you've got the idea backwards.
With the current format of your code you should be assuming it IS a palindrome and breaking when you discover it is not.
Instead you are assuming it is not, then setting it to "it is" the first time you see equality. But then the next time you see inequality you merely break without setting it to false again.
If I were to code this I wouldn't bother with a flag, I would merely return "false" the moment an inequality was found.
Your logic isn't right.
By default, you think the number is not a palindrome (flag=False), and if you see a mirrored int, you set the flag to true (if l[n]==l[i-n]: flag=True).
You should do the contrary. You should set the flag to True by default, and if an item is not mirrored, return a flag to False.
As pointed out by the fellow users, my code was clearly logically in the wrong. I was never setting back flag variable to False whenever I was exiting from the for loop. So I took in account the suggestions made and changed my code.
Here is the code following my previous solution with a flag variable:
def ispalindrome(n):
#creates a list for storing the element of the number one by one
l=[]
#storing the digits
while n!=0:
l.append(n%10)
n=int(n/10)
#setting useful variables
i=len(l)-1
flag=False
#traversing the list and checking whether palindrome
for n in range(0,len(l)):
#this block is executed only if n is less than (len(l)-1)-n
if n<i-n:
#comparing elements
if l[n]==l[i-n]:
#flag is set to true everytime l[n] equals l[(len(l)-1)-n]
flag=True
else:
flag=False
break
#if n>(len(l)-1)-n
else:
break
#returns the flag
return flag
#basic generator function that yields whenever ispalindrome() returns true
def palindromes(n=1111):
while True:
if ispalindrome(n): yield n
n+=1
#traversing through palindromes generator function
for n in palindromes():
if n>2552: break
print('{} is a palindrome'.format(n))
And here is the one suggested by both Blusky and Fredman (more efficient than mine to say the least):
def ispalindrome(n):
#creates a list for storing the element of the number one by one
l=[]
#storing the digits
while n!=0:
l.append(n%10)
n=int(n/10)
#setting useful variables
i=len(l)-1
#traversing the list and checking whether palindrome
for n in range(0,len(l)):
#this block is executed only if n is less than (len(l)-1)-n
if n<i-n:
#comparing elements
if l[n]!=l[i-n]:
#flag is set to true everytime l[n] equals l[(len(l)-1)-n]
return False
#if n>(len(l)-1)-n
else:
break
#returns the flag
return True
#basic generator function that yields whenever ispalindrome() returns true
def palindromes(n=1111):
while True:
if ispalindrome(n): yield n
n+=1
#traversing through palindromes generator function
for n in palindromes():
if n>2552: break
print('{} is a palindrome'.format(n))
P.S: I am neither a professional s/w dev nor have I access to high quality courses or a mentor, that's why question boards like stackoverflow is useful for me. I know this is a dumb question and if I thoroughly checked my code again and again I might have realized the mistake, but I don't think it requires a downvote, does it?

Receiving return None value

I am doing exercise from the book where I am supposed to write program that can take a positive integer greater than 2 and write out the number of times one must repeatedly divide this number by 2 before getting a value less than 2.
def inStr():
n = -1
while n<2:
try:
n = int(input('Enter a positive integer greater than 2: '))
except:
pass
print(positive(n)) # prints None
def positive(n, step=0):
if n < 2:
# print(step) #it prints correct answer
return step #but why it returns None?
positive(n//2, step+1)
inStr()
I don't understand why def positive(n, step=0) returns None?
It seems that you forgot to add return right before positive(n//2, step+1). So your function positive sometimes returns nothing (i.e. None).
Try this:
def inStr():
n = -1
while n<2:
try:
n = int(input('Enter a positive integer greater than 2: '))
except:
pass
print(positive(n)) # prints None
def positive(n, step=0):
if n < 2:
# print(step) #it prints correct answer
return step #but why it returns None?
return positive(n//2, step+1)
inStr()
Because you don't tell it to return anything else. You need to put return in there:
def positive(n, step=0):
if n < 2:
# print(step) #it prints correct answer
return step #but why it returns None?
return positive(n//2, step+1)
There may be times when a function calls itself, but doesn' want to return the results. You need to tell Python that this time you want to. Since you didn't tell Python what to return, it returns None by default.

calling the function, checking for palindromes in a range

I'm trying to make a function, which recursively checks for palindromes in a given range. The range is sent to "is_palindrome_multi", which then calls "is_palindrome".
However, it doesn't work with numbers higher then 10, so the limiting step seems to be:
elif data[0]==data[-1]:
statement. Why it doesn't return true for the numbers like 11, 22 and so on? I will be grateful for explanation.
def is_palindorme_multi(beg, end):
for i in range(beg, end):
i = str(i)
if is_palindrome(i) == True:
print "Palindrome"
else:
print "Not palindrome"
def is_palindrome(data):
print data,
if len(data)==1 or len(data)==0:
return True
elif data[0]==data[-1]:
is_palindrome(data[1:-1])
else:
return False
You are not returning the result of the recursive call.
Change your elif:
elif data[0]==data[-1]:
is_palindrome(data[1:-1])
to:
elif data[0]==data[-1]:
return is_palindrome(data[1:-1])
However, I would simply change your is_palindrome method to:
def is_palindrome(data):
return data == data[::-1]
Really, no need to use recursion here.

Categories