Palindrome with stacks - python

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:

Related

I have tried two methods to make a palindrome check that uses input but neither work. [Python]

I am trying to make a script that checks if input is a palindrome or not. I'm confused as to why neither of them work. In the first attempt, I printed reversed_phrase but it printed <list_reverseiterator object at 0x000001DDD1E27D60>. In the second attempt, I printed phrase[i] and reverse_phrase[i] in each iteration and they printed the same thing.
First Attempt:
original_phrase = input()
phrase = list(original_phrase)
reversed_phrase = reversed(phrase)
if phrase == reversed_phrase:
print(original_phrase, 'is a palindrome')
else:
print(original_phrase, 'is not a palindrome')
Second Attempt:
original_input= input()
phrase = list(original_input)
reversed_phrase = phrase
reversed_phrase.reverse()
is_palindrome = False
for i in range(0, len(phrase)):
print(phrase[i], reversed_phrase[i])
if phrase[i] != reversed_phrase[i]:
break
elif i >= len(phrase) - 1:
is_palindrome = True
if is_palindrome:
print(original_input, 'is a palindrome')
else:
print(original_input, 'is not a palindrome')
Your first solution is misusing the reversed(array) function as it returns a pointer to the end of the array so that you can iterate through it in reverse. What you want here is to actually reverse the array which is done with array.reverse();
Your second solution incorrectly always returns true because when you do this: reversed_phrase = phrase both reversed_phrase and phrase reference the same object, so any changes made to one appear when referencing either. What you want to do is reversed_phrase = phrase.copy() so that they are each individual versions of the array

Python giving unexpected return values in simple function

Here is the question:
Write a program to accept 2 inputs from user, a string and a list of letters. It should then display True if the entered string consists of all the letters in a given list.
And here is the solution I wrote:
def guess(secword,thelist):
for letter in thelist:
if letter not in secword:
return False
return True
word=str(input("Please enter a word"))
print("The length of your word is",len(word))
aList=[]
for i in word:
x=input("Please enter a character to add to the list")
aList.append(x)
print(aList)
print(guess(word,aList))
This solution I wrote works, however, if I change the code as such (adding an else statement):
def guess(secword,thelist):
for letter in thelist:
if letter not in secword:
return False
else:
return True
It does not work anymore.
Can anyone please provide an explanation?
Thanks for your time
Any return statement ends the function right there. In your broken code example
def guess(secword, thelist):
for letter in thelist:
if letter not in secword:
return False
else:
return True
(which is a quite typical beginner's gotcha) you return from the first iteration og the loop in every case. That means you are only examining the first element of the thelist.
def guess(secword, thelist):
for letter in thelist:
if letter not in secword:
return False
return True # you only know for sure after all are examined
def guess(secword,thelist):
for letter in thelist:
if letter not in secword:
return False
else:
return True
Think about what this is doing; it will check the first letter of the list, and if that letter is not present in secword it will correctly return false. If the letter is in secword, however, it will return true instantly without checking the rest of the letters in the word.
If I understand the question correctly, your initial function should be correct. That one will return false if any letter in the list is not in the word, and true otherwise.
Putting the "return True" inside the for-loop changes how it will work compared to the first solution. It will just check the first letter and return either False or True and exit from the function without looking at the rest of the letters.

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.

How to check if a word is a palindrome (Python)

Please help...
So the instruction says to program the computer to check whether a word is a palindrome or not. I inputted this code:
def is_palindrome(word):
counter_from_first_letter=0
counter_from_last_letter=-1
from_first_letter = word[counter_from_first_letter]
from_last_letter = word[counter_from_last_letter]
max_index_from_first= len(word)
max_index_from_last= (len(word))*-1
while from_first_letter == from_last_letter:
from_first_letter = word[counter_from_first_letter]
from_last_letter = word[counter_from_last_letter]
counter_from_first_letter += 1
counter_from_last_letter -= 1
return True
The problem is the computer only checks whether the first and last letters are the same, and if they are, it just returns true. How do I make sure the computer checks every single letter? Thanks
Maybe something like this:
def is_palindrome(word):
if word == word[::-1]:
return True
else:
return False
in python-3
name = 'madam'
print(name.find(name[::-1]) == 0)
Maybe you can try this: first convert your string into a list, then reverse the list and convert it back into a string. compare both the strings and if they match? they are palindromes, if not, they aren't.
'''checking whether a word is a palindrome
we first convert the word into a list then join it;
use an if statement to compare the two strings'''
def palindrome(string):#you need the input(string)
palindrome_check=[]#create an empty list
for character in string [::-1]:#create a list from the input
#(use a for loop because you now know the range)
#the [::-1] analyzes the characters in reverse
palindrome_check.append(character)#add each character to the new empty list
#print(palindrome_check)
rev_string= ''.join(palindrome_check)#.join -creates a string from the created list
print(rev_string)
#REMOVE SPECIAL CHARACTERS- IM THINKING OF A LOOPING THROUGH, BUT NOT SURE HOW TO IMPLEMENT IT
string=string.replace(' ', '')
rev_string=rev_string.replace(' ', '')
string=string.replace(',', '')
rev_string=rev_string.replace(',', '')
string=string.replace('.', '')
rev_string=rev_string.replace('.', '')
#THIS IS THE LOGIC: IT CHECKS BOTH STRINGS, if they are equal, it is a palindrome;
if string.lower()==rev_string.lower():
return True, print('It is a Palindrome')
else:
return False, print('It isnt a palindrome')
#call the function; key in the parameters-
palindrome= palindrome("No, Mel Gibson Is A Casinos Big Lemon")
#maybe we can try having a user key in the parameter? lets try
#palindrome=palindrome(input('kindly enter your word/phrase '))-wrong
#print('Kindly enter your word or phrase')
#user_palindrome=input('')
#palindrome=palindrome(user_palindrome)
#it wont work this way either
If you can have the user define the parameter(string), the better, if you know how to do this, kindly share.
To check whether a word or phrase is a palindrome, it be necessary to check if the original sentence is equal to the original sentence reversed.
word = "Eva can I see bees in a cave"
word_lower = word.lower().replace(" ", "")
if word_lower == word_lower[::-1]:
print("It's a palindrome")
else:
print("This is not a palindrome")

python secret word program

I'm trying to write a program where the user has to guess a letter in the goal of unlocking the secret word. If the secret word is guessed correctly before the maximum 8 guesses, the function returns true else the function returns false. For some reason my function just doesn't produce the right output. I would enter the letter 'a' and it would print "Letters guessed so far: ['a']" and then the program would end. I need help in fixing this issue.
secretWord = 'hello'
lettersGuessed = []
def isWordGuessed(secretWord,lettersGuessed):
guess = 0
while guess <= 8:
secretLetters = list(secretWord)
secretWordLen = len(secretLetters)
letter = input('Enter a letter: ')
lettersGuessed.append(letter)
print('Letters guessed so far: ',lettersGuessed)
if letter not in secretLetters:
guess += 1
while letter in secretLetters:
secretLetters.remove(letter)
if secretLetters == []:
return True
else:
return False
isWordGuessed(secretWord,lettersGuessed)
Your first problem is, as kwatford explained, that you are returning every time through the loop. You can fix that by moving the if statement outside the while loop.
Your next problem, as Vorticity explained, is that it will never return early, even if the user guesses the whole word. To fix that, move the if part back inside the loop, but leave the else part outside the loop (meaning you no longer need the else)
After that, it still won't work, because you're doing secretLetters = list(secretWord) each time through the loop, so you can only win if you guess all the letters in one guess (which is impossible, unless the word is, say, "a" or "aaaaa"). To fix that, move that line outside the loop.
Putting it all together:
def isWordGuessed(secretWord,lettersGuessed):
guess = 0
secretLetters = list(secretWord)
while guess <= 8:
secretWordLen = len(secretLetters)
letter = input('Enter a letter: ')
lettersGuessed.append(letter)
print('Letters guessed so far: ',lettersGuessed)
if letter not in secretLetters:
guess += 1
while letter in secretLetters:
secretLetters.remove(letter)
if secretLetters == []:
return True
return False
As a side note, there are a lot of things you can do to simplify this.
First, you really just need a set of all letters in the secret word—you don't need to know the order, or how many copies there are of each, etc. So, instead of a list, use a set. This also means you don't need the loop around secretLetters.remove(letter).
More trivially, you create secretWordLen but never use it.
You also accept and append to a lettersGuessed passed in by the caller, but the caller is just passing you an empty list, and never using it after the fact, so why bother? And if you don't need to mutate it for the caller's benefit, you can just keep it as a string, so the user sees help instead of ['h', 'e', 'l', 'p'], which is a lot nicer.
You've also got a few cases that are being tested even when they can't possibly be true.
Finally, an empty list (or set, or any other sequence) is false, so there's no reason to explicitly compare to the empty list.
While I'm at it, I'm going to PEP8-ify the spacing to make it easier to see the indentation.
So:
def isWordGuessed(secretWord):
guess = 0
lettersGuessed = ''
secretLetters = set(secretWord)
while guess <= 8:
letter = input('Enter a letter: ')
lettersGuessed += letter
print('Letters guessed so far:', lettersGuessed)
if letter not in secretLetters:
guess += 1
else:
secretLetters.remove(letter)
if not secretLetters:
return True
return False
The last if statement is indented too far, causing it to be part of your while loop. Since both branches of the condition cause the function to return, it always returns on the first iteration of the loop.
You just need to move your return for the False case. Basically, the way your code is written right now, you will never go back to the beginning of your loop. Also, as noted by abarnert, you will never exit the loop because you are reinitializing secretLetters every time you loop. You have to initialize it outside the loop. Your code should look like this:
secretWord = 'hello'
lettersGuessed = []
def isWordGuessed(secretWord,lettersGuessed):
guess = 0
secretLetters = list(secretWord)
secretWordLen = len(secretLetters)
while guess <= 8:
letter = input('Enter a letter: ')
lettersGuessed.append(letter)
print('Letters guessed so far: ',lettersGuessed)
if letter not in secretLetters:
guess += 1
while letter in secretLetters:
secretLetters.remove(letter)
if secretLetters == []:
#Return true if all correct letters have been guessed
return True
#Return false if guessed incorrectly eight times
return False

Categories