python: recursive check to determine whether string is a palindrome - python

My task is to define a procedure is_palindrome, that takes as input a string, and returns a boolean indicating if the input string is a palindrome. In this case a single letter should return True, as should an empty string ''.
Unfortunately, I'm not getting the expected results. I appreciate the help.
My code version 1:
def is_palindrome(s):
if s == '':
return True
else:
if (ord(s[0]) - ord(s[len(s)-1])) == 0:
is_palindrome(s[1:len(s)-1])
else:
return False
print is_palindrome('')
#>>> True (expected = True)
print is_palindrome('abab')
#>>> False (expected = False)
print is_palindrome('abba')
#>>> None (expected = True)
print is_palindrome('andrea')
#>>> None (expected = False)
print is_palindrome('abaaba')
#>>> None (expected = True)
I followed my code through the debugger and it seems the logic is correct as the code takes the appropriate path. However, the end result seems to switch to 'None' for some of the cases as highlighted above.
If I change my code to the following:
My code version 2:
def is_palindrome(s):
if s == '':
result = True
else:
if (ord(s[0]) - ord(s[len(s)-1])) == 0:
is_palindrome(s[1:len(s)-1])
else:
result = False
return result
print is_palindrome('')
#>>> True (expected = True)
print is_palindrome('abab')
#>>> False (expected = False)
print is_palindrome('abba')
#>>> Error (expected = True)
UnboundLocalError: local variable 'result' referenced before assignment
print is_palindrome('andrea')
#>>> Error (expected = False)
UnboundLocalError: local variable 'result' referenced before assignment
print is_palindrome('abaaba')
#>>> Error (expected = True)
UnboundLocalError: local variable 'result' referenced before assignment

In your first example, you forgot a return statement:
def is_palindrome(s):
if s == '':
return True
else:
if (ord(s[0]) - ord(s[len(s)-1])) == 0:
# v-- forgot this here
return is_palindrome(s[1:len(s)-1])
else:
return False

is_palindrome(s[1:len(s)-1])
needs to be...
return is_palindrome(s[1:len(s)-1])
in your first version, or
result = is_palindrome(s[1:len(s)-1])
in your second. Otherwise, you never actually propagate the recursive call's return value back to the original caller.

# ask user to enter any string
a = raw_input("Enter the string : ")
#palindrome check
print (a == a[::-1]) and "String is palindrome" or "String is not palindrome"

Let's step through your second example, line by line.:
def is_palindrome(s):
In this case let's let s = "abba", which is the first string you got an error on:
if s == '':
is evaluated as
if 'abba' == '':
Which is False, so we skip ahead to else:
else:
if (ord(s[0]) - ord(s[len(s)-1])) == 0:
This if statement is equivalent to:
if (97 - 97) == 0:
It's True, so recursion happens:
is_palindrome(s[1:len(s)-1])
or
is_palindrome('bb')
Now whatever is the result of this recursion, we ignore it, because the return value is not saved. Thus, when we get to this line:
return result
We never defined what result was, so Python flips out.
Other posters already did an excellent job of answering your question. I'm posting to demonstrate the importance of tracing a program to find/fix bugs.

def is_palindrome(s):
if not s:
return True
else:
return s[0]==s[-1] and is_palindrome(s[1:-1])
or, if you want a one-liner:
def is_palindrome(s):
return (not s) or (s[0]==s[-1] and is_palindrome(s[1:-1]))
Hope that helps

Respuesta en Java
public class Varios {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
System.out.println( pali("anitalavalatina"));
}
static boolean pali(String palabra){
System.out.println(palabra);
if (palabra.length()-1<2)
return true;
if(palabra.charAt(0)!=palabra.charAt(palabra.length()-1)) return false;
return pali(palabra.substring(1,palabra.length()-1));
}
}

Related

Trying to write a can it construct function getting a ValueError: substring not found error

def canConstruct(target, wordBank):
if target == '': #if there are no words in wordBank
return True
for word in wordBank:
if target.index(word) == 0: #checks if current word is current targets prefix
suffix = target.removeprefix(word)
if canConstruct(suffix, wordBank) == True:
return True
return False
print(canConstruct("eeeeeeeeeeeeeeeeeeeeeeeeeeeeef",["e","ee","eee","eeee","eeeee","eeeeee","eeeeeee"] ))
i dont get why it is throwing this error
ValueError: substring not found
Note that: removesuffix() is only available after Python v3.9. Doc
So if you are on earlier version, I think you can simply adjust your code as below:
def canConstruct(target, wordBank):
if (target == ''): return True
for word in wordBank:
if (target.startswith(word)):
suffix = target[len(word):]
if (canConstruct(suffix, wordBank) == 0):
return True
return False
You're getting that error because of this line:
if target.index(word) == 0:
If you pass a substring into the index method, and that substring doesn't exist within the superstring, than this error would occur.
For instance, if:
target = 'test string'
word = 'z'
When we try to index() target for word, the index() method won't be able to find word within target and will raise the exception you are having.
It's possible you simply have this line reversed, and are instead wanting to find target within word.
In that case you'll want to do this instead:
if word.index(target) == 0:
def canConstruct(target, wordBank):
if target == '':
return True
for word in wordBank:
if target.startswith(word):
suffix = target.removeprefix(word)
if canConstruct(suffix, wordBank) == True:
return True
return False
print(canConstruct("abcdef", ["ab", "abc", "cd", "def", "abcd", ]))

A python problem: is there any way to return a new string that ask for remove a certain part?

Given a string, if the string "app" appears starting at index 1, return a string where that "app" has been deleted. Otherwise, return the string unchanged.
oApp('hello') → 'hello'
oApp('aapppotato') → 'apotato'
oApp('appmello') → 'appmello'
below is what I have until now...
def oApp(string):
for i in range(len(string)):
if string[1] == "app":
return string[0] + [3:]
else:
return string
This is the solution:
oApp = lambda x: x[0]+x[4:] if x[1:].startswith('app') else x
assert oApp('hello') == 'hello'
assert oApp('aapppotato') == 'apotato'
assert oApp('appmello') == 'appmello'
Those assertion will not raise some errors, therefore it is working as intended.

Python function returns True or 1 as None, while returning False and 0 correctly

I have a program that does a simple palindrome check, by comparing each ends of the string and then doing a substring of the original string recursively. That is, I compare str[0] to str[-1], do a str[1,-1] and repeat the comparisons. What I did find while stepping through the code is, that when I ask the function check_palin() to return 1, it returns None. I can clearly see it 'execute' the return statement, but it always returns None when I ask it to return 1. However, it returns 0 correctly. The same behavior is observed with returning True/False. Here is my code. What am I doing wrong??
def check_palin(s):
global init
print("Init is %d" %(init))
if len(s) <= 1 :
if not init :
print("returning 1")
return True
else :
print("Please supply a string of atleast 2 characters! Exiting...\n")
print("returning 0")
return False
else :
init = 0
if first_word(s) == last_word(s) :
check_palin(middle(s))
else :
print("returning 0")
return False
def first_word(s) :
return s[0]
def last_word(s):
return s[-1]
def middle(s):
return s[1:-1]
init = 1
s = raw_input("Please enter a string")
print(check_palin(s))
if not check_palin(s) :
print ("String %s IS NOT a palindrome!" %(s))
else :
print ("String %s IS a palindrome!" %(s))
Output:
Please enter a stringababa
Init is 1
Init is 0
Init is 0
returning 1
None
Init is 0
Init is 0
Init is 0
returning 1
String ababa IS NOT a palindrome!
Process finished with exit code 0
You forgot to return the result of your recursion.
if first_word(s) == last_word(s) :
return check_palin(middle(s))

Python: Controlling using if [duplicate]

This question already has answers here:
What is the purpose of the return statement? How is it different from printing?
(15 answers)
Closed 6 months ago.
I have this code:
def the_flying_circus():
if True and True and True and not False:
print "Kevin stinkt"
elif 10 < 4:
print "Justin stinkt"
else:
print "herb-wuerzig"
When I print the_flying_circus I get Kevin stinkt printed, None as a return. I would need False as return for an online tutorial. Why do I get None, and how can I achieve an True?
None is the return value of the function. A function that finishes without an explicit return statement will return None.
In response to your additional question:
If you want the function to return true, put
return True
at the end. If you want it to return false, put
return False
at the end.
The function returns None if it does not return anything else, hence you first print inside the function and then you print the None that was returned.
If you either exchange your print statements with return or just call the_flying_circus() instead of print the_flying_circus() you will get the expected result.
def the_flying_circus():
if True and True and True and not False:
return "Kevin stinkt"
elif 10 < 4:
return "Justin stinkt"
else:
return "herb-wuerzig"
Then you can run the function and print the returned value:
print the_flying_circus()
Or you can do:
def the_flying_circus():
if True and True and True and not False:
print "Kevin stinkt"
elif 10 < 4:
print "Justin stinkt"
else:
print "herb-wuerzig"
And just call the function without printing the returned value:
the_flying_circus()
The code needed is the following:
# Make sure that the_flying_circus() returns True
def the_flying_circus(antwort):
if antwort > 5:
print "H"
elif antwort < 5:
print "A"
else:
print "I"
return True
what ever input I give, the_flying_circus always returns True

variable 'cmd_part_1' referenced before assignment

I keep having this error on my bot program:
start.py:890 local variable 'cmd_part_1' referenced before assignment
Code:
try:
my_alias = message.body.split(" ", 3)
if len(my_alias) > 2:
cmd_part_1 = my_alias[0]
cmd_part_2 = my_alias[1]
elif len(my_alias) < 2:
cmd_part_1 = ""
cmd_part_2 = ""
except Exception as e:
cmd_part_1 = ""
cmd_part_2 = ""
if self.getAccess(user.name.lower()) >= lvl_config.rank_req_callme and cmd_part_1 == "call" and cmd_part_2 == "me":
whole_body = message.body
whole_body = whole_body.replace("call me ", "");
whole_body = whole_body.replace(",", ",");
chat_message("<font color='#%s' face='%s' size='%s'>%s <b>%s</b></font>" % (font_color, font_face, font_size, random.choice(["Recorded! ^_^ I will now call you", "Registah'd, you are now", "Yo, dis mah big homie, I call dem", "Ye-a-a-ah, I guess I can call you that...", "If I have to.. I suppose I'll call you..", "I decided I will call you"]), whole_body), True)
alias_flag = 0
finished_proc = 1
file = open("storage/flatfile/various/aliases.csv", "r")
for line in file.readlines():
alias_data = line.strip()
alias_username, alias_nickname = alias_data.split(",", 1)
Error Line:
if self.getAccess(user.name.lower()) >= lvl_config.rank_req_callme and cmd_part_1 == "call" and cmd_part_2 == "me":
What am I doing wrong?
You have if and elif statements in the first try block that set cmd_part_1.
What happens if none of the conditions in these if statements is True?
In that case, cmd_part_1 will never be assigned a value. This is what is going on in your code. Fix this and it will work. Maybe add an else clause there and assign a default value to both cmd_part_1 and cmd_part_2. Or make one of them have an =.
For example:
if len(my_alias) >= 2:
instead of:
if len(my_alias) > 2:
After that, as eryksun suggested in the comment below, you can replace the elif with an else.

Categories

Resources