Python palindrome code doesn't return anything - python-2.7

Why?
It returns:
if word[0] != word[-1]:
IndexError: list index out of range
If I change "print "Palindrome"" to "return True" and "return False" it returns nothing at all.
import sys
exstring = "f"
data = list(exstring)
def palindrome(word):
if len(word) < 2:
print "Palindrome"
if word[0] != word[-1]:
print "Not Palindrome"
return palindrome(word[1:-1])
palindrome(data)

First, you need an elif in there like Hypnic Jerk mentioned. Second you need to return after your prints.
Working code:
import sys
exstring = "radar"
data = list(exstring)
def palindrome(word):
if len(word) < 2:
print "Palindrome"
return True
elif word[0] != word[-1]:
print "Not Palindrome"
return False
return palindrome(word[1:-1])
palindrome(data)

What you want to do is this:
def palindrome(word):
if len(word) < 2:
return True
if word[0] != word[-1]:
return False
return palindrome(word[1:-1])
You do not need elif in this case. It's just good practice. The second if statement will not be reached unless the first is false anyway. More "correct" (but still completely equivalent) is:
def palindrome(word):
if len(word) < 2:
return True
elif word[0] != word[-1]:
return False
else
return palindrome(word[1:-1])
Furthermore, it's good practice to only let the function decide if it's a palindrome or not, and not print it. Instead, you should use it like this:
if palindrome(word):
print "Palindrome"
else
print "Not palindrome"
Don't mix functionality unless you have a good reason.

Related

How to avoid repeating the same 'else' statement in multiple nested if/else?

In the code below, 'else' is same for all 'if' statements? Is there a way to have just one 'else' statement, rather than repeating the same code in all 'if' statement blocks for 'else' statement?
Here's example:
if condition A == "Yes":
print("A")
if condition B == "Yes":
print("B")
else:
print("D")
if condition C =="Yes":
print("C")
else:
print("D")
else:
print("D")
Flowchart
In the case of nested if else, you can use a guard type statement. guard is popular in case of nested if-else and provides a clean code.
Guard statement tries to element the else cases first. You know we write else cases to perform deviated paths. So what if we remove the
deviated paths first.
For example, if you have
if condition A == "Yes":
print("A")
if condition B == "Yes":
print("B")
else:
print("D")
if condition C =="Yes":
print("C")
else:
print("D")
else:
print("D")
Now I can formatting the following
// 1
if condiation A == "No" {
print("D")
return
}
// 2
if condition B == "Yes" {
print("B")
return
}
if condition C == "No" {
print("D")
return
}
print("C")
For more follow the link: - Youtube
You look like in a nested testing sequence
You test A
if A ok, you test B
if B ok you test C
if any test fail you print D
so ...
you eitheir leave the testing sequence test everything print all Yes result
or print D if any test fail (wich look like a big ERROR message)
or
you keep the ugly if else sequence
If you go for testing everything
you can create a function
def TestThis(Value, id):
if value == "Yes":
print(id)
return 1
else:
return 0
and call it like this:
if TestThis(A, "A") == 0:
integrity = 1
elif TestThis(B, "B") == 0:
integrity = 1
elif TestThis(C, "C") == 0:
integrity = 1
if integrity == 1:
print("D")
And I'm pretty sure you can find a way to finally get your sequence testing.
Edited to create that sequential testing that was the aim from the start

Python Breaking a While Loop with user input

new to Python. Within a while loop, I'm asking the user for an input which is a key for a dict. and then print the value of that key. This process should continue until the input does not match any key in the dict. I'm using an if statement to see if the key is in the dict. If not I'like the while loop to break. So far I can't get it to break.
Thank you all
Animal_list = {
'lion': 'carnivora', 'bat': 'mammal', 'anaconda': 'reptile',
'salmon': 'fish', 'whale': 'cetaceans', 'spider': 'arachnida',
'grasshopper': 'insect', 'aligator': 'reptile', 'rat': 'rodents',
'bear': 'mammal', 'frog': 'amphibian', 'turtles': 'testudines'
}
while True:
choice = raw_input("> ")
if choice == choice:
print "%s is a %s" % (choice, Animal_list[choice])
elif choice != choice:
break
choice == choice will always be true. What you really want to do is check if choice is in the Animal_list. Try changing to this:
Animal_list = {
'lion': 'carnivora', 'bat': 'mammal', 'anaconda': 'reptile',
'salmon': 'fish', 'whale': 'cetaceans', 'spider': 'arachnida',
'grasshopper': 'insect', 'aligator': 'reptile', 'rat': 'rodents',
'bear': 'mammal', 'frog': 'amphibian', 'turtles': 'testudines'
}
while True:
choice = raw_input("> ")
if choice in Animal_list:
print "%s is a %s" % (choice, Animal_list[choice])
else:
break

Wrote a nested if else procedure that returns the answer AND "none". Why?

def is_friend (name):
if name[0] == 'D':
print 'yes'
else:
if name [0] == 'N':
print 'yes'
else:
print 'no'
print is_friend ('Eric')
no
None
Use return on your if else statements instead of print and then it will work.
def is_friend(name): if name[0] == 'D': return 'yes' else: if name[0] == 'N'return 'yes' else: return 'no'
print is_friend('Eric')

I have found most of everything I need and have a "mostly" working game

I having issues with the def check guess. It's the format my teacher specifically gave. You guys are great. Thanks for the help!!!! Sorry for the format this is my first time on this site.
# # Global variables
wrong_guesses = []
target_phrase = ""
current_phrase = ""
def clear_display():
for i in range(20):
print "\n"
def string_with_dashes(str):
global target_phrase
new_phrase = ""
for i in str:
if i.isalpha():
new_phrase += "-"
else:
new_phrase += i
return new_phrase
def check_guess(letter):
global current_phrase
replacement_list = [""]
for i in range(len(target_phrase)):
if target_phrase[i] == letter:
replacement_list[i] = target_phrase[i]
current_phrase = replacement_list
return current_phrase
else:
wrong_guesses.append(letter)
return False
def process_input():
user_letter = raw_input("Guess a letter: ").upper()
if user_letter in wrong_guesses:
print "You already guessed that letter"
user_letter = raw_input("Guess again : ")
else:
return check_guess(user_letter)
def one_turn():
global wrong_guesses
print "=================================================="
print current_phrase
print "Wrong guesses:", ' '.join(wrong_guesses)
print "Guesses remaining:", (8 - len(wrong_guesses))
display_robot(8 - len(wrong_guesses))
print "String to guess:", current_phrase
print "=================================================="
process_input()
print "\n\n"
def setup_phrase():
global target_phrase, current_phrase
target_phrase = raw_input("Dear friend, enter a phrase for the user to guess: ").upper()
current_phrase = string_with_dashes(target_phrase)
setup_phrase()
clear_display()
while True:
one_turn()
if len(wrong_guesses) > 7:
print "GAME OVER! You Lose"
breack
if current_phrase == target_phrase:
print "You WIN!!"
break
(why won't stackoverflow let me fix your code?)
I'm not sure exactly what you are trying to do, but it sounds like you want to create a string where the guessed letters replace blanks as they are guessed? Try something like this:
hidden_phrase = "abracadabra"
current_list = ["."]*len(hidden_phrase)
def check_guess(letter):
for i in range(len(hidden_phrase)):
if hidden_phrase[i] == letter:
current_list [i] = hidden_phrase[i]
print("before", "".join(current_list ))
check_guess("a")
print("guess1", "".join(current_list))
check_guess("z")
print("guess2", "".join(current_list))
check_guess("b")
print("guess3", "".join(current_list))
Output:
before ...........
guess1 a..a.a.a..a
guess2 a..a.a.a..a
guess3 ab.a.a.ab.a
In Python strings are immutable, and can't be updated, so it seems easier to me to keep the 'replacement' word (with blanks, which I represent with .) as a list, and join it back together for display.
The two global variables don't need to be explicitly specified as global, because the variable is not assigned to in the function, only accessed.
If you prefer to have a string current_phrase and update that, of course that's possible too:
hidden_phrase = "abracadabra"
current_phrase = "."*len(hidden_phrase )
def check_guess(letter):
global current_phrase
i = -1
while True:
i = hidden_phrase.find(letter, i+1)
if i<0:
break
current_phrase = current_phrase[0:i]+letter + current_phrase[i+1:]
print("before", current_phrase)
check_guess("a")
print("guess1", current_phrase)
check_guess("z")
print("guess2", current_phrase)
check_guess("b")
print("guess3", current_phrase)
This time you need the global again to prevent current_phrase = ... from creating a local variable.
My previous answer was to the first, more general, version of your question. Several things were wrong with your check_guess(). Here's a fixed version:
def check_guess(letter):
global current_phrase
replacement_list = list(current_phrase)
found=False
for i in range(len(target_phrase)):
if target_phrase[i] == letter:
replacement_list[i] = target_phrase[i]
found = True
if found:
current_phrase = "".join(replacement_list)
else:
wrong_guesses.append(letter)
Comments to show problems with your version:
def check_guess(letter):
global current_phrase
replacement_list = [""] # list has only 1 element, can't assign above index zero
for i in range(len(target_phrase)):
if target_phrase[i] == letter:
replacement_list[i] = target_phrase[i]
current_phrase = replacement_list # assigning a list to what was previously a string
return current_phrase # returns before checking 2nd character
else:
wrong_guesses.append(letter) # only the first character has been checked
return False # returns False or current_phrase, inconsistent
Also near the end you wrote breack instead of break, it's a shame that Python doesn't check these things by default, waiting instead for you to hit that line.

return result of palindrome check with for-loop in python

I am doing a palindrome-check assignment in Python. I have to use a for-loop to check if it is a palindrome or not.
I think that I am on to the right track, but I am having trouble returning the result of the loop. When running the program it always returns True, even when it is not a palindrome. I would really need help to see if I have done the for-loop correctly and how to return the correct result.
My program as it is now looks like this:
def main ():
showResult(testPalindrome(newText()))
def newText():
word = raw_input ('Hi, insert a word:')
clean = (',','!','.')
for i in clean:
cleanedText = word.replace(i, "").lower()
return cleanedText
def testPalindrome(cleanedText):
testword = cleanedText
list = [testword]
for i in range(len(list)/2):
if list[i] != list [-i-1]:
continue
else:
break
def showResult(palindrome):
if True:
print 'Yes, it is a palindrome '
else:
print 'No, it is not palindrome'
main ()
You never return anything from test_palindrome. Remember that it is not a palindrome if any letters fail to match, but all must match to pass, so:
for i in range(len(list)/2):
if list[i] != list [-i-1]:
continue
else:
break
Should become
for i in range(len(list)/2):
if list[i] != list [-i-1]:
return False
return True
Also, to make your code more robust, you could replace clean with string.punctuation (remembering to import string).
For testing is a string is a palindrome, compare it with its reverse.
In [1]: p = 'this is a test'
In [2]: p[::-1]
Out[2]: 'tset a si siht'
In [3]: p == p[::-1]
Out[3]: False
In [4]: q = 'racecar'
In [5]: q == q[::-1]
Out[5]: True