Recursive Program: What am I doing wrong? - python

I am trying to write a code that would analyze if a word is a palindrome.
BTW a palindrome is a word that is read the same backward and forward. Example are "madam" or "noon"
Here is a try:
x = raw_input("please enter a word:\n")
L = len(x)
# this part returns the first letter of the word
def first(word):
return word[0]
# this part returns the last letter of the word
def last(word):
return word[-1]
def middle(word):
return word[1:-1]
def is_palindrome(word):
if L <= 2:
print 'enter a word with at least three letters'
elif first(word) != last(word):
print 'This word is not a palindrome'
else:
word = middle(word)
is_palindrome(word)
is_palindrome(x)
But when executed, I get
IndexError: string index out of range
...line 7, in first return word[0]
The first branch of "is_palindrome" works perfectly. i.e. when the word is not a palindrome, I get no errors. Like "noopn" is executed with no errors, but the error is in the second branch
I've playing with this code for so many times but can't figure out the "iterative part" I have the answer but I don't want to look at it yet. I need to figure out two things:
1. a way to make the iteration in the function is_palindrome work correctly?
and 2. a way to exit the program in the end.
Could you folks direct me to how to answer these questions without providing the solution yet?
Finally where should I put the print statement: print 'This word is a palindrome'
Thank you

To accomplish your goal, why don't just use:
string[::-1] == string
And the reason for your answer is when there is only 1 letter, middle will return an empty string and then ''[0] will cause the error.

You need a base case for your recursion. A one letter word is a palindrome, and an empty string is also a palindrome.
def is_palindrome(word):
# handle the base case
if len(word) <= 1:
print 'This word is a palindrome'
elif first(word) != last(word):
print 'This word is not a palindrome'
else:
word = middle(word)
is_palindrome(word)
If you want to reject words with fewer than three letters, then you can use a helper function that calls the recursive function:
def is_palindromeHelper(word):
if len(word) <= 2:
print 'enter a word with at least three letters'
else:
is_palindrome(word)

Personally, I would prefer separating the check and the output. So is_palindrome() should just return the answer and not be responsible for telling the user. That makes it more reusable.
def is_palindrome(word):
# handle the base case
if len(word) <= 1:
return True
elif first(word) != last(word):
return False
else:
word = middle(word)
return is_palindrome(word)
This enables you to do
x = raw_input("please enter a word:\n")
L = len(x)
if L <= 2:
print 'enter a word with at least three letters'
elif is_plaindrome(word):
print 'This word is a palindrome'
else:
print 'This word is not a palindrome'
This puts the validity check to the front of the execution, while in the recursion, you have only the checks which are valid all over the recursion.
(I doubt if your check is necessary at all - are y and oo no palindromes? We could argue about the empty string, however...)
The next improvement steps could be to omit the functions first(), last() and middle() - they are trivial and only used once, so you could put there code where they are used.

Added an extra condition in your code , which will solve your problem. You don't need to call is_palindrome() , when you have just a single character left
x = raw_input("please enter a word:\n")
L = len(x)
# this part returns the first letter of the word
def first(word):
return word[0]
# this part returns the last letter of the word
def last(word):
return word[-1]
def middle(word):
return word[1:-1]
def is_palindrome(word):
if L <= 2:
print 'enter a word with at least three letters'
elif first(word) != last(word):
print 'This word is not a palindrome'
else:
word = middle(word)
if len(word) > 1:
is_palindrome(word)
else:
print 'This word is a palindrome'
is_palindrome(x)

A basic version without considering capitalization and white-space, I'd suggest:
def is_palindrome(word):
if len(word) < 3:
print 'Enter a word with at least three letters'
else:
for letter in range(len(word)/2):
if word[letter] != word[-letter - 1]:
print "This word is not a palindrome"
return
print "This word is a palindrome"
Though I think it might personally remove white space and make the comparisons using .lower(). Then it will be case insensitive and allow for testing a phrase or sentence also.

Great directions guys. All got an upvote.
These directions allowed me to make the following concise codes
Code 1
x = raw_input("enter a word to check if it is a palindrome:\n")
if x[::-1] == x:
print 'yes this one is a palindrome'
else:
print 'sorry try again by re-running the program'
Code 2
x = raw_input("enter a word to check if it is a palindrome:\n")
if len(x) <= 1:
print 'Of course ', x, ' is a palindrome'
def is_palindrome(x):
if len(x) >= 2:
if x[0]!=x[-1]:
print 'This is not a palindrome'
else:
x = x[1:-1]
return is_palindrome(x)
print 'This is FINALLY a real palindrome'
is_palindrome(x)
I guess I could include the function is_palindrome as a second branch of the conditional statement len(x) <= 1, but I like it better this way since the code is all about this function

Related

Removing non alpha numeric characters from string and splitting strings words into a list to see if a condition has been met using regular expressions

I am completing a program that takes a sys argument(string) and checks if it's a palindrome or not. My current code works if I have a single-word string. However, I need to make sure the program would check each individual word and not factor in any non alphanumeric characters. If any of the words are a palindrome then it would print it's a palindrome a single time.
Thought process:
My thoughts were to split each word into a list, have the list iterated to see if the condition has been met, and print only one time. If I have multiple words it prints out it's not a palindrome. Currently, it will just print it's not a palindrome multiple times if I provide a string with multiple words: ie 'racecar, racecar'
Any suggestions would be much appreciated.
Here is my code so far;
def palindrome():
string = sys.argv[1].lower()
remove_punc = string.strip('~`!#$%^&*()_-+={}[]|\:;<,>.?/')
converted_string = remove_punc.split(' ')
for i in converted_string:
if converted_string == converted_string[::-1]:
print('It\'s a palindrome!')
break
else:
print('It\'s not a palindrome!')
palindrome()
When you enter more than 1 word (thing with a space before or after),
you need to take all the arguments but the program itself, if your want to have each word. Then you clean them from non alpha chars, then you can test them.
import sys
def palindromes():
words = sys.argv[1:]
cleaned_words = [
w.strip('~`!#$%^&*()_-+={}[]|\:;<,>.?/')
for w in words
]
for word in cleaned_words:
if word == word[::-1]:
print(f'{word} is a palindrome!')
else:
print(f'{word} is not a palindrome!')
palindromes()
Test:
$ python palindromes.py foo aba bar boob
foo is not a palindrome!
aba is a palindrome!
bar is not a palindrome!
boob is a palindrome!
Do you mean this?
import re
s = "aaa bbb, aaa"
s = re.sub("[^A-z]", "", s)
print(s == s[::-1])
Update
With no regex:
s = "Al lets Della call Ed “Stella.”"
s = "".join([x for x in s.lower() if 123>ord(x)>96])
print(s == s[::-1])
To work with args:
s = sys.argv[1]
s = "".join([x for x in s.lower() if 123>ord(x)>96])
print(s == s[::-1])
Update 2
If you want to check several palindromes at once, here you go:
import sys
for s in sys.argv[1:]:
x = "".join([x for x in s.lower() if 123>ord(x)>96])
print("'"+ s + "' is a palindrome? ", x == x[::-1])
I appreciate the submissions and this is the main part that worked for me.
new_string = ''.join(i if i.isalpha() else '' for i in string)
if new_string == new_string[::-1]:
print('It\'s a palindrome!')
else:
print('It\'s not a palindrome!')

How can I make sure a word is palindrome using Python while using recursion?

I am trying to create a code in which python asks the user for input or a word and it has to check whether it's a palindrome or not using recursion. If the word is not a palindrome through the reverse() function it will take in the string and, through recursion, return that string in reverse. It seems that I am able to take input and when I put in a word that's not a palindrome it gives me back the output needed. However it doesn't give back the word in reverse and also when I put a word that is a palindrome and it doesn't give the input back leaving a blank space in the output.
def reverse(choice, index, new_word):
if index < 0:
return new_word
else:
new_word += choice[index]
return reverse (choice, index - 1, new_word)
def palindrome():
new_word = ""
choice = input("Please enter a word to check if it is palindrome:")
result = reverse(choice, len(choice) - 1, new_word)
if result == choice:
print("That word",choice,"IS a palindrome")
else:
print("Sorry,",new_word,"is NOT a palindrome")
palindrome()
This is happening because you have set new_word to an empty string, and then you're taking the result of reverse() and storing that in another variable called result.
This should fix your issue:
def palindrome():
new_word = ""
choice = input("Please enter a word to check if it is palindrome:")
result = reverse(choice, len(choice) - 1, new_word)
if result == choice:
print("That word",choice,"IS a palindrome")
else:
# change here to result
print("Sorry,",result,"is NOT a palindrome")
Alternatively, you can use choice[::-1] to reverse a string. it is cleaner and you don't have to use recursion. However, the above fix will help you with the recursion bit as well.
Try the following:
def check_palindrome(word): # Creating function with 1 parameter: word
if word == word[:: -1]: # word[:: -1] reverses a string
return True # Return a true value if word is the same when reversed
else:
return False # Otherwise, return a false value
print(check_palindrome("racecar")) # Palindrome
print(check_palindrome("hello world")) # Not a palindrome
the syntax word[:: -1] reverses the word.

Palindrome with stacks

So I'm trying to check if a word is a palindrome using stacks. I've gotten it work with one exception. If I try the word 'level' it works, however, if I try 'levell' it comes back true. Here's my code:
import Stack
def check_palindrome():
s = Stack.Stack()
word = input('Enter a word: ')
for x in word:
s.push(x)
palindrome = True
for x in range(len(word)):
if s.pop() == word[x]:
palindrome = True
else:
palindrome = False
if palindrome == True:
print(word, 'is a palindrome.')
else:
print(word, 'is not a palindrome.')
check_palindrome()
I can't seem to figure out why it is saying it's true. Maybe I'm thinking about this incorrectly. My train of thought was to add each letter to the stack using
for x in word:
s.push(x)
Then to pop it because of FILO and compare the last to the first. Any insight would be appreciated!
Of course, there are much better ways to check that a word is a palindrome, using reversed string and comparing to itself for instance (there are a ton of answers on this site solving this).
That said, about your problem:
for x in range(len(word)):
if s.pop() == word[x]:
palindrome = True
else:
palindrome = False
If one letter doesn't match, it should break the loop, or else the answer is conditioned only by the last loop iteration. I'd write:
for letter in word:
if s.pop() != letter:
palindrome = False
break # one mismatch: bail out
else:
palindrome = True # OK
(else of the for loop is executed only if all iterations were achieved without encountering break)
I don't know if you intentionally want to use Stack, why not check if the word is equal to its reverse, like so?
def check_palindrome(word):
palindrome = word == word[::-1] # True if word is equal to its reverse
if palindrome == True:
print(word, 'is a palindrome.')
else:
print(word, 'is not a palindrome.')
The problem is that your comparison continues even after you find a mismatch, so palindrome can get reset to True even after it gets set to False. So overall, you're actually only checking if the first and last letter of your word is the same. You can fix this by breaking out of the loop when you find a mismatch.
Also just as a style note, you can replace if palindrome == True: with if palindrome:

Palindrome Function Python

I'm trying to write a function that will tell me if the inputted word or phrase is a palindrome. So far my code works but only for single words. How would I make it so that if I enter something with a space in it like 'race car' or 'live not on evil' the function will return true? Other questions on this page explain how to do it with one words but not with multiple words and spaces. Here what I have so far...
def isPalindrome(inString):
if inString[::-1] == inString:
return True
else:
return False
print 'Enter a word or phrase and this program will determine if it is a palindrome or not.'
inString = raw_input()
print isPalindrome(inString)
You could add the characters of the string to a list if the character is not a space. Here is the code:
def isPalindrome(inString):
if inString[::-1] == inString:
return True
else:
return False
print 'Enter a word or phrase and this program will determine if it is a palindrome or not.'
inString = raw_input()
inList = [x.lower() for x in inString if x != " "] #if the character in inString is not a space add it to inList, this also make the letters all lower case to accept multiple case strings.
print isPalindrome(inList)
Output of the famous palindrome "A man a plan a canal panama" is True. Hope this helps!
You just need to split it by the spaces and join again:
def isPalindrome(inString):
inString = "".join(inString.split())
return inString[::-1] == inString
Slightly different approach. Just remove spaces:
def isPalindrome(inString):
inString = inString.replace(" ", "")
return inString == inString[::-1]

checking if the first letter of a word is a vowel

I am trying to use python to write a function that checks whether the first letter of a given word, for instance "ball" is a vowel in either uppercase or lowercase. So for instance:
#here is a variable containing a word:
my_word = "Acrobat"
#letters in vowel as a list
the_vowel = ["a","e","i","o","u"]
How do a check that the first letter in "Acrobat" is one of the vowels in the list? I also need to take into consideration whether it is upper or lowercase?
try my_word[0].lower() in the_vowel
I don't know if it is better than the answers already posted here, but you could also do:
vowels = ('a','e','i','o','u','A','E','I','O','U')
myWord.startswith(vowels)
Here are some hints to help you figure it out.
To get a single letter from a string subscript the string.
>>> 'abcd'[2]
'c'
Note that the first character is character zero, the second character is character one, and so forth.
The next thing to note is that an upper case letter does not compare equal to a lower case letter:
>>> 'a' == 'A'
False
Luckily, python strings have the methods upper and lower to change the case of a string:
>>> 'abc'.upper()
'ABC'
>>> 'a' == 'A'.lower()
True
To test for membership in a list us in:
>>> 3 in [1, 2, 3]
True
>>> 8 in [1, 2, 3]
False
So in order to solve your problem, tie together subscripting to get a single letter, upper/lower to adjust case, and testing for membership using in.
my_word = "Acrobat"
the_vowel = "aeiou"
if myword[0].lower() in the_vowel:
print('1st letter is a vowel')
else:
print('Not vowel')
My code looks like this.
original = raw_input("Enter a word:")
word = original.lower()
first = word[0]
vowel = "aeiou"
if len(original) > 0 and original.isalpha():
if first in vowel:
print word
print first
print "vowel!"
else:
print word
print first
print "consonant
x = (input ("Enter any word: "))
vowel = "aeiouAEIOU"
if x[0] in vowel:
print ("1st letter is vowel: ",x)
else:
print ("1st letter is consonant: ",x)
Here's how I did it since the inputted word needs to be checked first before storing it as a variable:
original = raw_input('Enter a word:')
if len(original) > 0 and original.isalpha():
word = original.lower()
first = word[0]
if first in ['a','e','i','o','u']:
print "vowel"
else:
print "consonant"
else:
print 'empty'
changes:
if my_word[0] in ('a','e','i','o','u'):
print(' Yes, the first letter is vowel ')
else:
print(' No, the first letter is not vowel ')
So, Here is the simple code for finding out that the first letter is either vowel or not!! If you have any further query in python or js, then comment it down.
import ast,sys
input_str = sys.stdin.read()
if input_str[0] in ['a','e','i','o','u','A','E','I','O','U']:
print('YES')
else:
print('NO')
Here is the solution to the exercise on codecadmy.com:
original = raw_input('Enter a word:')
word = original.lower()
first = word[0]
vowel = "aeiou"
if len(original) > 0 and original.isalpha():
if first in vowel:
print 'vowel'
else:
print 'consonant'
else:
print 'empty'
Will it not be (slightly) faster to define the_vowel as a dictionary than a list?
the_vowel = {"a":1,"e":1,"i":1,"o":1,"u":1}
my_word[0].lower() in the_vowel
anti vowel Function
def anti_vowel(text):
vowel = ["a","e","i","o","u"]
new_text = ''
for char in text:
if char.lower() in vowel:
continue
else:
new_text += char
print new_text
return new_text
x = raw_input("Enter a word: ")
vowels=['a','e','i','o','u']
for vowel in vowels:
if vowel in x:
print "Vowels"
else:
print "No vowels"
This would print out 5 lines, if any of those includes a line that says Vowels then that means there is a vowel. I know this isn't the best way but it works.
Let's do it in more simply way
def check_vowel(s1):
v=['a','e','i','o','u']
for i in v:
if s1[0].lower()==i:
return (f'{s1} start with Vowel word {i}')
else:
return (f" {s1} start with Consonants word {s1[0]}")
print(check_vowel("orange"))
inp = input('Enter a name to check if it starts with vowel : ') *# Here we ask for a word*
vowel = ['A','E','I','O','U', 'a','e','i','o','u'] *# This is the list of all vowels*
if inp[0] in vowel:
print('YES') *# Here with the if statement we check if the first alphabet is a vowel (alphabet from the list vowel)*
else:
print('NO') *# Here we get the response as NO if the first alphabet is not a vowel*
my_word = "Acrobat"
the_vowel = ["a", "e", "i", "o", "u"]
if my_word[0].lower() in the_vowel:
print(my_word + " starts with a vowel")
else:
print(my_word + " doesnt start with a vowel")
input_str="aeroplane"
if input_str[0].lower() in ['a','e','i','o','u']:
print('YES')
else:
print('NO')
Output will be YES as the input string starts with a here.

Categories