Homework exercise:
Checking whether a text is a palindrome should also ignore punctuation, spaces and case. For example, "Rise to vote, sir." is also a palindrome but our current program doesn't say it is. Can you improve the above program to recognize this palindrome?
origin code:
def reverse(text):
return text[::-1]
def is_palindrome(text):
return text == reverse(text)
something = input('Enter text: ')
if (is_palindrome(something)):
print("Yes, it is a palindrome")
else:
print("No, it is not a palindrome")
my try:
import re
def reverse(text):
global words
words = text.split()
return words[::-1]
def is_palindrome(text):
return words==reverse(text)
something = input('Enter text: ')
if (is_palindrome(something)):
print("Yes, it is a palindrome")
else:
print("No, it is not a palindrome")
Error:
Enter text: jfldj
Traceback (most recent call last):
File "/Users/apple/PycharmProjects/Problem Solving/user_input.py", line 13, in <module>
print("Yes, it is a palindrome")
File "/Users/apple/PycharmProjects/Problem Solving/user_input.py", line 10, in is_palindrome
NameError: name 'words' is not defined
How should I change my code?
Latest code:
import string
def remove_punctuations(word):
return "".join(i.lower() for i in word if i not in string.ascii_letters)
def reverse(text):
return text[::-1]
def is_palindrome(text):
text = remove_punctuations(text)
return text == reverse(text)
something = input('Enter text: ')
if (is_palindrome(something)):
print("Yes, it is a palindrome"
else:
print("No, it is not a palindrome")
No matter what I input, output is Yes.
Enter text: hggjkgkkkk
Yes, it is a palindrome
What's wrong?
To ignore the punctuations, spaces and case of the given text you need to define a function remove_punctuations() which takes a word as parameter and returns a word with all lower case characters, remove punctuation marks and removed spaces.
To remove the unwanted characters we need to iterate over the given text, if the current character falls in strings.ascii_letters , then generate the character converting it to lower caps using str.lower() method. Finally using "".join() method to concatenate the generated str elements.
import string
def remove_punctuations(word):
return "".join(i.lower() for i in word if i in string.ascii_letters)
def reverse(text):
return text[::-1]
def is_palindrome(text):
text = remove_punctuations(text)
return text==reverse(text)
something = "Rise to vote, sir."
if (is_palindrome(something)):
print("Yes, it is a palindrome")
else:
print("No, it is not a palindrome")
Since the hint says to use a tuple with forbidden punctuation marks, I created the following variant:
forbidden = (' ', ',', "'", '?', '!', '.', '’')
def reverse(text):
return text[::-1]
def cleaning(text):
clean_text = ''
for item in text:
if item not in forbidden:
clean_text += item
return clean_text
def is_palindrome(text):
lower_text = cleaning(text.lower())
return lower_text == reverse(lower_text)
example = input('Enter something: ')
if is_palindrome(example):
print("Yes, it is a palindrome")
else:
print("No, it is not a palindrome")
The cleaning function checks each character for belonging to a tuple of forbidden characters, if not, then concatenates it to the clean_text string
I started studying for python 2 days before so that is what i come up with.
It is not so much advanced but works like a charm. :D
It is pretty straight forward what i do there. I just make a tuple with the "legal" letters (abc=). Then I define a function that 1st change all letters to lower case and then checks every character in the string with the "legal" letters. Then after this "filtering" the rawtext contains only the "legal" ones. Then the 2nd function just reverses the results of the 1st one. Compare and da da..!
# Palindrome recognize
abc='abcdefghijklmnopqrstuvwxyz'
def rawtext(text):
rawtext=''
text=text.lower()
for j in text[::1]:
for i in abc[::1]:
if j==i:
rawtext=rawtext+j
return rawtext
def reverse(text):
rev= rawtext(text)[::-1]
return rev
text=str(input('Write text:'))
if reverse(text)==rawtext:
print('The text is palindrome')
else:
print('The text is not a palindrome')
from itertools import izip_longest
def is_palindrome(s):
l = len(s)
fi = (i for i in xrange(l) if s[i].isalpha())
bi = (i for i in xrange(l-1, -1, -1) if s[i].isalpha())
for f, b in izip_longest(fi, bi):
if f >= b: return True
if s[f].lower() != s[b].lower(): return False
return True
Hope that helps
Related
For the get_letter_from_user function, while using the while loop for validation, it keeps repeating the invalid input; I want to make sure that it is a single letter and lower case, and I want to make sure that it doesn't equal the second parameter of the function. I'm not sure what I'm doing wrong, though. (and how to get gud at coding if u have tips)
def get_text_from_user(prompt):
return input(prompt).lower()
def get_letter_from_user(prompt, not_allowed):
not_allowed = ''
allowed = input(prompt).lower()
while not allowed == not_allowed or allowed.isalpha() or len(allowed) > 1:
allowed = str(input('Invalid letter, try again:'))
return allowed
def main():
text = get_text_from_user("Enter some text: ")
ltr1 = get_letter_from_user("Enter a letter: ", '')
ltr2 = get_letter_from_user("Enter another letter: ", ltr1)
new_text = text.replace(ltr1,ltr2)
print("The new text is", new_text)
if __name__ == "__main__":
main()
Suggestion for the function:
def get_letter_from_user(prompt, not_allowed):
allowed = input(prompt).lower()
while allowed == not_allowed or len(allowed) > 1:
print('not_allowed:',not_allowed)
allowed = str(input('Invalid letter, try again:'))
return allowed
ltr1 = get_letter_from_user("Enter a letter: ", '')
ltr2 = get_letter_from_user("Enter another letter: ", ltr1)
Sample output:
Enter a letter: d
Enter another letter: d
not_allowed: d
Invalid letter, try again:d
not_allowed: d
Invalid letter, try again:a
To replace a letter or sequence of letters in a string, you might want to take a look at the string.replace() function:
text = input('Enter some text: ')
find = input('Enter a letter to replace: ')
replace_with = input(f'Enter a letter to replace \'{find}\' with: ')
replaced = text.replace(find, reolace_with)
print('The new text is:', replaced)
To add another little detail because you asked how to get better at coding:
I would never make a function with a parameter that is immediately changed to an empty string. Like:
def get_letter_from_user(prompt, not_allowed):
not_allowed = ''
Rather use a default value like this:
def get_letter_from_user(prompt, not_allowed=''):
...
I've written a validation function that looks like this:
def validateFloat(self, text):
if (text == ''):
return True
try:
float(text)
return True
except ValueError:
return False
But I can still enter spaces after I enter a digit. I want to make it so that it doesn't allow spaces, only dots and digits.
Thanks in advance.
If you only want to catch spaces
def validateFloat(self, text):
if (text == ''):
return True
elif ' ' in text:
return False
try:
float(text)
return True
except ValueError:
return False
You can simply use
x=isinstance(text,float)
if text variable is float, this will return true.
To remove space from text use strip function as mentioned below.
text.strip()
If you want to check whitespace in text. Use below
if ' ' in text:
I'm still learning the ropes with my programming and have run into an issue that I can't seem to solve after searching for the answers
I have a while loop that is checking if a dictionary is not empty, or if the user entered a specific character (escape character).
The program works as expected if the user enters the escape character on the first prompt but seems to not function correctly if they first enter something else and then try it.
Can anyone help?
hand = {'p':1, 'y':1, 't':1, 'h':1, 'o':1, 'n':1}
def play_hand(hand):
print hand
word = raw_input('Enter word, or a "." to indicate that you are finished: ')
while any(hand) is True or word not in '.':
if word == '.':
break
elif (word == 'toy' or word == 'python') and (word != '.'):
print '"'+ word +'"', 'earned', 'points.'
play_hand(hand)
else:
print 'Invalid word, Please try again.'
return word, play_hand(hand)
else:
print 'Ending'
return
So as suggested I restructured the code and removed the recursion from the inner IF ELSE statements. It did the trick!
Thanks for the help.
Here's the sample from above done in the same fashion. You can now enter the valid word and also exit using the escape character.
hand = {'p':1, 'y':1, 't':1, 'h':1, 'o':1, 'n':1}
def play_hand(hand):
while any(hand) is True:
print hand
word = raw_input('Enter word, or a "." to indicate that you are finished: ')
if word == '.':
print 'Goodbye!'
break
else:
if not (word == 'toy'):
print 'Invalid word, Please try again.'
else:
print '"'+ word +'"', 'earned', 'points.'
hand = {'p':1, 'h':1, 'n':1}
The following code will not run nor will it show an error message. Please help. Also, how would I add a function to display only the output of this code?
def main():
s= ""
phrase=""
programdescription(s)
userinput(phrase)
#This function displays the program description
def programdescription(s):
s = print("This program determines if a word, phrase, or sequence can be read the same backward as forward.")
#This function requests user input for analysis
def userinput(phrase):
phrase = input("Enter a word or phrase: ")
def s_phrase(phrase):
phrase = phrase.upper()
strippedPhrase = ""
for char in phrase:
if (48 <= ord(char) <= 57) or (65 <= ord(char) <= 90):
strippedPhrase += char
flag = True
n = len(strippedPhrase)
for j in range(int(n / 2)):
if strippedPhrase[j] != strippedPhrase[n - j - 1]:
flag = False
break
if flag:
print(phrase, "is a palindrome.")
else:
print(phrase, "is not a palindrome.")
main()
Ok, problem 1 is you never call s_phrase.
Problemo 2 is that the phrase variable can't be seen by s_phrase.
Problem numero C is that your indentation is messed up.
Issue 4 is more the fact that this seems like a very 'C' way of tackling the challenge. Borrowing from Spade, here is a more succinct way of doing it that is formatted to your original program.
def main():
s= ""
phrase=""
programdescription(s)
s_phrase(phrase)
#This function displays the program description
def programdescription(s):
s = print("This program determines if a word, phrase, or sequence can be read the same backward as forward.")
#This function requests user input for analysis
def s_phrase(phrase):
phrase = input("Enter a word or phrase: ")
phrase = phrase.upper()
r_phrase = phrase[::-1]
print(r_phrase)
if phrase == r_phrase:
print(phrase, "is a palindrome.")
else:
print(phrase, "is not a palindrome.")
main()
I am currently working on a hangman project. I am having problems with hiding characters in words with asterisks - like, "word" would be ****, then when the player makes a guess and it's correct, the letter would appear where it should be, instead of the asterisk, like if you guessed 'o', *o**. How can I do this?
This is my current code.
import random
start = 1
class hangman():
def __init__(self):
self.__word = word
self.__incorrectg = none
word = random.choice(open(input("please type the file you wish to open ")).readlines())
print (word)
lettercount = len([ltr for ltr in word if ltr.isalpha()])
print (lettercount)
If you stored the players guesses in a list for instance:
used_letters = [] # and append guesses to this, both right and wrong
so as soon as the user inputs a guess, you append it to used_letters.
with open(filepath) as f: # this might be a better way to open the file
word = random.choice(f.readlines()) # after this statement the file is auto closed, and frees up the memory
and you have the actual word stored as a list as in:
word = list(word) #made into a list of the letters in the word
then you could do something like:
guessed_string = ''.join(letter if letter in used_letters else '*' for letter in the_word)
EDIT:
#prints out the starred string. i.e. unguessed letters are '*' and guessed letters that appear in the word appear as normal letters.
print guessed_string
let me know if this works for you.
Example:
if word = 'arbitrary'
word = list(word) gives:
['a','r','b','i','t','r','a','r','y']
if the user has so far guessed:
used_letters = ['a', 'b', 'e', 'r']
then
guessed_string = ''.join(letter if letter in used_letters else '*' for letter in word)
print guessed_string
will give:
'arb**rar*'
value="C9T1573518"
new_value=value[0:3]
new_value+="".join(value[l].replace(value[l],"*") for l in range(3,len(value),1))
print(
new_value
)
#!/usr/bin
def password(word):
class __password:
def __repr__(self):
return "*" * len(word)
return __password()
word = password("Mypassword123")
print word
Took a while but I was finally able to get it:
#!/usr/bin
def password(word):
external_repr = set()
class __password:
def __repr__(self):
return ''.join(word[i] if word[i] in external_repr else '*' for i in xrange(len(word)))
def __eq__(self, somestring):
return word == somestring
def guess(self, letter):
external_repr.add(letter[0])
def encrypt(self):
return "*" * len(word)
return __password()
word = password("Mypassword123")
if word == "Mypassword123": print "Passwords match!"
print "The encrypted password is", word.encrypt()
word.guess('s')
print "After your guess, the word is now", word