UnboundLocalError Leetcode #5. Longest Palindromic Substring - python

Leetocode keeps giving me this UnboundLocalError, and I don't know why...
This is my code
class Solution:
def longestPalindrome(self, s: str) -> str:
def isPalindrome(s):
if len(s) == 1:
return True
if len(s) == 2 and s[0] == s[1]:
return True
else:
if s[0] == s[-1]:
return isPalindrome(s[1:-1])
else:
return False
max_ = 0
lenght = len(s)
for i in range(lenght):
for r in range(i + 1, lenght):
if isPalindrome(s[i:r]):
len_ = r - i + 1
if len_ > max_:
max_ = len_
final = s[i:r]
return final
and the error it gives me is
UnboundLocalError: local variable 'final' referenced before assignment
return final
Can someone please help me understand why this may be occurring?
I think the problem may be given in the case where the final string is of len() = 1. In that case it might be a problem the s[i : r]

your final variable is defined inside the if block and is not visible outside. just declare it outside to get rid of this erro
class Solution:
def longestPalindrome(self, s: str) -> str:
def isPalindrome(s):
if len(s) == 1:
return True
if len(s) == 2 and s[0] == s[1]:
return True
else:
if s[0] == s[-1]:
return isPalindrome(s[1:-1])
else:
return False
max_ = 0
lenght = len(s)
final = 0 # declared final here
for i in range(lenght):
for r in range(i + 1, lenght):
if isPalindrome(s[i:r]):
len_ = r - i + 1
if len_ > max_:
max_ = len_
final = s[i:r]
return final

Testcase in which s consist of only one letter. like ("a","d") your inner for loop is not executing and hence you define final inside the if is not initialize and you are returning final hence unbound error occurs.
for ex. let's say s="s"
Dry run-:
max_ :0
lenght :1 (i.e len(s))
for i in range(1):
for j in range(1,1) (i.e when first loop iterating i=0) no inner loop run
Exit()
return Final #Unbound error
To solve this error you can initialize final outside. or you can add a condition if len(s)==1: return 1
also your code solution has time complexity O(n^2) I think it will show Time limit exceeded.

Related

Why am I getting nonetype when calling a function within a function in Python?

I'm tying to do a Collatz sequence with python code. I'm supposed to make a function that, given n, calculates the next number in the sequence. I want the next function "write" to print each number within the sequence.
My code so far:
def collatz(n):
while n != 1:
if n % 2 == 0:
n = n/2
return write(n)
else:
n = 3*n+1
return write(n)
def write(n):
print(n)
print(collatz(n))
write(6)
It gives me the right sequence, which should be 6, 3,10,5,16,8,4,2,1, but also gives me 9 "nones".
I'm new to programming, it should probably be something easy, but I can't figure out what.
write() is a function that executes two print() statements, and then implicitly returns None (since there are no return statements in the function).
You can simplify the code by using print() directly in collatz(), and eliminating the mutual recursion:
def collatz(n):
while n != 1:
if n % 2 == 0:
n = n//2
print(n)
else:
n = 3*n+1
print(n)
collatz(6)
#Here this will help you understand.
#When n becomes 1, the while loop is not executed,
#collatz does not return write(n)... thus returns None
def collatz(n):
while n != 1:
if n % 2 == 0:
n = n/2
return write(n)
else:
n = 3*n+1
return write(n)
#return None.... there is no return type, so this is implied
def write(n):
print(n)
result = collatz(n)
if result != None:
print(collatz(n))

Generating pattern based on odd and even integers

I need help with converting my iterative code to recursive.
def pattern(int):
if int == 0:
return ''
else:
result = '*-'
for i in range(int-1):
if i%2 != 0:
result += '*-'
elif i % 2 == 0:
result += '*--'
return result
Above is the code I wrote to convert an integer into repetitive patterns. For int%2 != 0, it prints '*-' , and for int%2 == 0, it prints '*--'.
I have been stucked with converting the above to recursive. I understand the base case is '*-' with the terminating condition of int == 1. I should then concatenate the base case with pattern(int-1) recursively. Can anyone advise me?
IIUC, Use:
def pattern(n):
if n == 1: # Base case
return "*-"
if n % 2 == 0:
return pattern(n - 1) + "*--"
else:
return pattern(n - 1) + "*-"
Calling the function:
print(pattern(10)) # builds the pattern corrensponding to integers from 1,2...10.
This prints:
*-*--*-*--*-*--*-*--*-*--

LeetCode 762 why is separate code works in Jupiter Notebook and not in Leetcode

I am working on leetcode "762. Prime Number of Set Bits in Binary Representation" and I tested my code works fine on Jupiter Notebook and when I migrate into leetcode it shows null as a ending result. Could someone give me any hint on what the problems are?
class Solution:
def countPrimeSetBits(self, L, R):
"""
:type L: int
:type R: int
:rtype: int
"""
def isPrime(num):
if num == 0:
return False
list1 = list(range(num))
list1.remove(0)
if len(list1) != 0:
list1.remove(num-1)
for i in list1:
if num % (i+1) == 0:
return False
else:
return True
count = 0
for i in range(L, R+1):
newlist = list(bin(i)[2::])
newcount = 0
for j in newlist:
if j == '1':
newcount += 1
if isPrime(newcount) is True:
count += 1
return count
The expect result is 23 for the first test case which is L=842 and R=888
Jupiter Note book gives me back 23 as expected but Leetcode returns null as a result
You have two serious problems. The first is that the code as presented is indented incorrectly, such that the body of code for countPrimeSetBits() is instead part of the internal function isPrime(). The second problem is that, besides being the worst implementation ever, your isPrime() doesn't really work:
>>> isPrime(169)
True
>>> 13 * 13
169
>>>
due to this else clause placing the return at the wrong point in the code:
else:
return True
Below is your patched code which hopefully will work in both environments:
class Solution:
def countPrimeSetBits(self, L, R):
"""
:type L: int
:type R: int
:rtype: int
"""
def isPrime(number):
if number == 0:
return False
divisors = list(range(number))
divisors.remove(0)
if divisors:
divisors.remove(number - 1)
for divisor in divisors:
if number % (divisor + 1) == 0:
return False
return True
count = 0
for i in range(L, R + 1):
newlist = list(bin(i)[2::])
newcount = 0
for j in newlist:
if j == '1':
newcount += 1
if isPrime(newcount):
count += 1
return count

For loop doesn't work with bool return in function function

I really don't know what to do.
This is what I'm trying to do:
If a number in my lst is bigger than 'a' and smaller than 'b', the function has to return true. else, false.
What's wrong here?
def is_in_range(lst,a,b):
for num in lst:
if num> a and num < b:
return True
i+=1
elif num >=b:
return False
return c
elif num <= a:
return False
elif len(lst) ==0:
return True
print is_in_range([1,2,3,5],0,4)
The function prints me true unless b = the first number in my lst.
Actually your indentation and control flow is not really clear. But based on your description this would solve your problem:
def is_in_range(lst, a, b):
return any(a < num < b for num in lst)
This is quite generic as well, if you would like to see that ALL the numbers are in the range, you would only have to change any to all.
To take it closer to what you started off with:
def is_in_range(lst, a, b):
if len(lst) == 0:
return True
for num in lst:
if a < num < b:
return True
return False
Note that each function returns only once, thus if no corresponding value was found, only then will you return with False.

Error: Unsupported Operand Types

I'm trying to use recursion to return the dot product of two lists, and I'm trying to account for the situation in which I get two lists of different length: I return 0. However, when I try to check for that condition, I get the error: unsupported operand type(s) for &: 'list' and 'list'. Why can't I use the '&' operand for two lists in Python?
def dot(L, K):
if L+K == []:
return 0
elif L == [] & K != []:
return 0
elif K == [] & L != []:
return 0
else:
return L[-1] * K[-1] + dot(L[:-1], K[:-1])
I would probably do something like this:
def dot(L, K):
if L + K == [] or len(L) != len(K): # this only needs to be checked once
return 0
return dot_recurse(L, K)
def dot_recurse(L, K):
if len(L) > 0:
return L[-1] * K[-1] + dot_recurse(L[:-1], K[:-1])
else:
return 0;
def dot(L, K):
if len(L)!=len(K): # return 0 before the first recursion
return 0
elif not L: # test if L is [] - previous test implies K is [] so no need to retest
return 0
else:
return L[-1] * K[-1] + dot(L[:-1], K[:-1])
Your code is a bit more complicated than it really needs to be. It is not possible to take the dot product of two vectors which are not the same size. There are a couple of ways to deal with receiving vectors of different sizes.
1) Lop off the remaining unused numbers from the larger vector. Below is a modified version of your function. I changed it to only require one check for if either of the vectors is empty (there is no need to check this in multiple ways), and also changed it to start from the beginning of the vectors instead of the end. Was there a particular reason you started from the end?
def dot(L, K):
if(L == [] or K == []):
return 0
else:
return L[0] + K[0] + dot(L[1:], K[1:])
While this option works, it does not give the user any indication that they made a mistake in attempting to dot product two different sized vectors.
2) Give the user an error upon receiving two different sized vectors.
def dot(L, K):
if(len(L) != len(K)):
print('Vector sizes do not match, please pass two same-sized vectors')
return 0 #not sure exactly how you are wanting to do error handling here.
elif(L == [] or K == []):
return 0
else:
return L[0] + K[0] + dot(L[1:], K[1:])
If you check out python's Operator Precedence you will see that & has lower precedence than == and and
This means you are doing the following:
if (L == ([] & K)) != []:
...
As suggested by Tuan333 you should be using and.
def dot(L, K):
if L+K == []:
return 0
elif L == [] and K != []:
return 0
elif K == [] and L != []:
return 0
else:
return L[-1] * K[-1] + dot(L[:-1], K[:-1])
However if you wanted to use & (which is the Binary AND, and isn't the same thing) you could just use () to force precedence
def dot(L, K):
if L+K == []:
return 0
elif (L == []) & (K != []):
return 0
elif (K == []) & (L != []):
return 0
else:
return L[-1] * K[-1] + dot(L[:-1], K[:-1])
If you're curious why & is likely not what you want read on:
AND takes two values, converts them to Booleans (True or False) and check that both are True
Binary AND (&) takes two values, converts them to a Number-like value, then performs an operation on their bits
Here is how I would implement this function
def dot(L, K):
if len(L) != len(K):
# Ensure the lists are the same length
raise ValueError('Can not perform dot product on two differently sized lists')
elif len(L) + len(K) == 0:
# See if we've reached the base case
return 0
else:
# Recurse doing dot product
return L[-1] * K[-1] + dot(L[:-1], K[:-1])
print(dot([6, 2, 6], [5, 1]))

Categories

Resources