'IF' condition misbehaving - python

Here is a code that determines whether an input is PRIME number or not.
def is_prime(x):
for n in range(2, x - 1):
if x < 2 or x % n == 0:
return False
else:
return True
But the if condition inside the for loop doesn't work as expected. If x < 2, it should return false. So is_prime(1) should return false as 1 is less than 2. But the program returns True instead, which is not expected. On the other hand, if you put that if just outside the for loop like this, IT WORKS:
def is_prime(x):
if x < 2: return False
for n in range(2, x - 1):
if x % n == 0:
return False
else: return True
Why is this happening?

Over here,
for n in range(2, x - 1):
the for loop never runs if x == 1, then, you are essentially saying:
for n in range(2, 0):
which can't happen, so it just returns True from the else statement.
Your second function works because, as you said, the if statement is outside of the for loop

def is_prime(x):
if x < 9:
return x in {2, 3, 5, 7}
elif not (x % 2):
# even
return False
else:
upto = int(x ** 0.5) # test to sqrt(x)
# test divisibility by odd numbers
return all(x % div for div in range(3, upto+1, 2))

Related

Palindrome number in python (leetcode)

class Solution:
def isPalindrome(self, x: int) -> bool:
# If x is a negative number it is not a palindrome
# If x % 10 = 0, in order for it to be a palindrome the first digit should also be 0
if x < 0 and x%10 == 0):
return False
reversedNum = 0
while x > reversedNum:
reversedNum = reversedNum * 10 + x % 10
x = x // 10
# If x is equal to reversed number then it is a palindrome
# If x has odd number of digits, dicard the middle digit before comparing with x
# Example, if x = 23132, at the end of for loop x = 23 and reversedNum = 231
# So, reversedNum/10 = 23, which is equal to x
return True if (x == reversedNum or x == reversedNum // 10) else False
This is my code which is giving wrong output for 660,
Expected output : False
My output : True
Can someone tell me how to correct this.
reversedNum = 0
Num=x
while x > 0:
reversedNum = reversedNum * 10 + x % 10
x = x // 10
return True if (Num == reversedNum) else False
You don't really need an explicit check for a negative number because the while loop (in the following code) will not be entered and the return value will be an equality test between zero and some negative number - which is obviously False.
So:
def ispalindrome(x):
n = x
r = 0
while n > 0:
r *= 10
r += n % 10
n //= 10
return r == x
if you convert the number to a string is very simple. you only need to check that the string written backwards is the same
def ispalindrome(x):
return str(x) == str(x)[::-1]
ispalindrome(23132)
>>> True

Function to evaluate validity of numerical palindrome for floating point numbers using Python

So there are plenty of algorithms to evaluate whether an int is a palindrome, i.e.
def ReverseNumber(n, partial=0):
if n == 0:
return partial
return ReverseNumber(n // 10, partial * 10 + n % 10)
or this one:
def isPalindrome(x):
if (x < 0):
return False
div = 1
while (x / div >= 10):
div *= 10
while (x != 0):
l = x / div
r = x % 10
if (l != r):
return False
x = (x % div) / 10
div /= 100
return True
However what I'd like to do is assess whether a number such as 1.01 or 22.22 and so on, whether such numbers are themselves palindromes.
How could either of those algorithms above be adapted to function for floats in addition to ints?
This is the code I'm using to call it:
import sys
# This method determines whether or not the number is a Palindrome
def isPalindrome(x):
x = str(x).replace('.','')
a, z = 0, len(x) - 1
while a < z:
if x[a] != x[z]:
return False
a += 1
z -= 1
return True
if '__main__' == __name__:
trial = int(sys.argv[1])
# check whether we have a Palindrome
if isPalindrome(trial):
print("It's a Palindrome!")
The simplest thing to do is just convert the number to a string, then compare characters from the ends to the middle. The string conversion is less expensive than repeated multiplications and divisions.
def isPalindrome(x):
x = str(x).replace('.','')
a, z = 0, len(x) - 1
while a < z:
if x[a] != x[z]:
return False
a += 1
z -= 1
return True

Fast Prime Generator besides Sieve

I recently made this bit of code, but wonder if there is a faster way to find primes (not the Sieve; I'm still trying to make that). Any advice? I'm using Python and I'm rather new to it.
def isPrime(input):
current = 0
while current < repetitions:
current = current + 2
if int(input) % current == 0:
if not current == input:
return "Not prime."
else:
return "Prime"
else:
print current
return "Prime"
i = 1
primes = []
while len(primes) < 10001:
repetitions = int(i)-1
val = isPrime(i)
if val == "Prime":
primes.append(i)
i = i + 2
print primes[10000]
here is a function that detect if x is prime or not
def is_prime(x):
if x == 1 or x==0:
return False
elif x == 2:
return True
if x%2 == 0:
return False
for i in range(3, int((x**0.5)+1), 2):
if x%i == 0:
return False
return True
and another implementation that print prime numbers < n
def prime_range(n):
print(2)
for x in range(3, n, 2):
for i in range(3, int((x**0.5)+1), 2):
if x%i == 0:
break
else:
print(x)
hope it helps !
If you are not using a sieve, then the next best are probably wheel methods. A 2-wheel checks for 2 and odd numbers thereafter. A 6-wheel checks for 2, 3 and numbers of the form (6n +/- 1), that is numbers with no factors of 2 or 3. The answer from taoufik A above is a 2-wheel.
I cannot write Python, so here is the pseudocode for a 6-wheel implementation:
function isPrime(x) returns boolean
if (x <= 1) then return false
// A 6-wheel needs separate checks for 2 and 3.
if (x MOD 2 == 0) then return x == 2
if (x MOD 3 == 0) then return x == 3
// Run the wheel for 5, 7, 11, 13, ...
step <- 4
limit <- sqrt(x)
for (i <- 5; i <= limit; i <- i + step) do
if (x MOD i == 0) then return false
step <- (6 - step) // Alternate steps of 2 and 4.
end for
return true
end function
I leave it to you to convert that into Python.
As in
n = 10000
for p in range(2, n+1):
for i in range(2, p):
if p % i == 0:
break
else:
print p
print 'Done'
?

Why does my boolean function sometimes return None?

Using Python 3.4. Have attempted to call function prime/2 that returns a boolean--always either True or False--from within an IF-statement. The function is expensive to run, so I want to call it only when I know it is needed, hence calling from within a decision point. The called function does not reliably return True/False. Sometimes the return is None, at which point the test fails. I use Python's IDLE and its debugger. I call primes(2, 5, []) and step through the code. When prime/2 reaches line elif n <= p while n = 5 and p = 5, the debugger shows that prime/2 returns True, as it should, but the line in primes/3 elif prime(m, 2) takes a value of None. And at that point my test fails. My code:
def primes(m, n, l): # the calling function
if m > n: # creates a list of primes from
print(l, end='\n') # m through n, inclusive
elif m < 2:
primes(2, n, l)
elif m == 2:
l.append(2)
primes(3, n, l)
elif m % 2 == 0:
primes(m + 1, n, l)
elif prime(m, 2): # calling the second function
l.append(m) # to test m for primality
primes(m + 2, n, l)
else:
primes(m + 2, n, l)
def prime(n, p): # the called function will return
if n < 2: # True if m is prime, False otherwise
return False
elif n < 4:
return True
elif n <= p:
return True
elif (n > 2) and (n % p == 0):
return False
elif p == 2:
prime(n, 3)
else:
prime(n, p + 2)
The error is in how you call prime() recursively. You need to explicitly return the value. Like this:
def prime(n, p): # the called function will return
if n < 2: # True if m is prime, False otherwise
return False
elif n < 4:
return True
elif n <= p:
return True
elif (n > 2) and (n % p == 0):
return False
elif p == 2:
return prime(n, 3) # <--- RETURN VALUE
return prime(n, p + 2) # <--- & RETURN VALUE

Python: break out of multiple levels of loop

I have this pseudocode for a Miller-Rabin primality tester:
function isPrime(n, k=5)
if n < 2 then return False
for p in [2,3,5,7,11,13,17,19,23,29]
if n % p == 0 then return n == p
s, d = 0, n-1
while d % 2 == 0
s, d = s+1, d/2
for i from 0 to k
x = powerMod(randint(2, n-1), d, n)
if x == 1 or x == n-1 then next i
for r from 1 to s
x = (x * x) % n
if x == 1 then return False
if x == n-1 then next i
return False
return True
But translating that to Python is hard because of the next i statement in the inner for loop, which must break two loops. There is no goto in Python. Other questioners who have asked this question on Stack Overflow have been told to use a local function with a return, or a try/except condition, or an additional boolean flag, but those solutions either don't apply here or would greatly uglify this lovely pseudocode.
What is the Pythonic approach to this problem?
I think the pythonic approach would be try/except, readability would prefer a method or a boolean, but I think that this is solvable by adding a single line:
for i in xrange(k):
x = powerMod(randint(2, n-1), d, n)
if x == 1 or x == n-1: continue
for r in xrange(1,s):
x = (x * x) % n
if x == 1: return False
if x == n-1: break #*
if x != n-1: #added line
return False
return True
breaking on the line marked with #* is problematic because it returns false, but if we fix that it's just like "next i".
Another solution, suggested by tobias_k, is to use for/else:
for i in xrange(k):
x = powerMod(randint(2, n-1), d, n)
if x == 1 or x == n-1: continue
for r in xrange(1,s):
x = (x * x) % n
if x == 1: return False
if x == n-1: break
else: #added line
return False
return True
return False statement would not be called if the loop was break-ed - only if it was exhausted.
You can use break and continue witn a for: else.
for i from 0 to k
x = powerMod(randint(2, n-1), d, n)
# Use 'continue' to go to next i (skip inner loop).
if x == 1 or x == n-1 then next i
for r from 1 to s
x = (x * x) % n
if x == 1 then return False
# Use 'break' to exit this loop and go to next i
# since this loop is at the end of the i loop.
if x == n-1 then next i
else:
# This is only reached if no `break` occurred
return False
return True

Categories