Find And Replace Character In Python - python

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=''):
...

Related

The code will not run nor will it show an error message

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()

infinite loop in Hangman game in Python

I am trying to build a simple Hangman game, but the following program is creating an infinite loop when the letter entered by the user is not part of the word to guess (it's printing "*" indefinitely). What is missing here? Any advice would be appreciated.
import re
import random
folder = open("datas.txt","r")
data = folder.read()
word_list = re.sub("[^\w]"," ", data).split()
chosen_word = random.choice(word_list)
letter_player = input('enter a letter pls:\n')
continue_game = False
masked_word = []
for letter in chosen_word:
masked_word.append("*")
found_letters = []
def guess_letter():
for letter in range(0,len(chosen_word)):
if letter_player == chosen_word[letter]:
found_letters.append(letter_player)
masked_word[letter] = letter_player
else:
masked_word[letter] = '*'
print(masked_word[letter])
return found_letters
str_found_letters = ''.join(found_letters)
print(str_found_letters)
if(str_found_letters != chosen_word):
continue_game = True
while continue_game:
guess_letter()
As there are others answering, why not hand out another try, from where the OP could continue? So here another version fixing also the overwrite error of previous found letters in subsequent iterations.Note also, that the append of letters found in a list may be what one wants, or maybe not, as the o in foo would be appended twice.
# Python 3/2, imports and a literal:
from __future__ import print_function
import re
import random
MASK_CHAR = '*'
# Read words from file and select randomly:
def read_game_data(source="datas.txt"):
"""Randomly select a word from source data."""
with open(source, "r") as f_data:
return random.choice(re.sub("[^\w]", " ", f_data.read()).split())
# Build sequences (here lists) of letters that constitute a word or "mask"
def build_word_seq(a_word, a_mask=None):
return [letter if not a_mask else a_mask for letter in a_word]
# the core evaluation function (previously named guess_letter)
def evaluate_letter(chosen_word, masked_word, letter_player, found=None):
if found is None:
found = set()
for pos in range(len(chosen_word)):
if letter_player == chosen_word[pos]:
found.add(letter_player)
masked_word[pos] = letter_player
return masked_word, found
# The function that replaces the continue_game variable:
def not_ready(chosen_word, masked_word):
"""Evaluate."""
return True if masked_word != chosen_word else False
# Put the business in a main function, minimize globals:
def main():
"""Do the game."""
chosen_word = build_word_seq(read_game_data())
mask = build_word_seq(chosen_word, a_mask=MASK_CHAR)
found_letters = set()
while not_ready(chosen_word, mask):
letter_player = input('enter a letter pls:\n')
mask, found_letters = evaluate_letter(
chosen_word, mask, letter_player, found_letters)
print(''.join(mask))
if found_letters:
print("LettersFound: %s" % (sorted(found_letters),))
if __name__ == '__main__':
main()
A typical run based on a datas.txt file with:
foo bar baz
yes
no
yields e.g:
$ python3 hangman_again_inf_loop.py
enter a letter pls:
f
***
enter a letter pls:
y
***
enter a letter pls:
b
b**
LettersFound: ['b']
enter a letter pls:
a
ba*
LettersFound: ['a', 'b']
enter a letter pls:
r
bar
LettersFound: ['a', 'b', 'r']
The loop again may be infinite (if you do not guess right ;-)
For a hangman game, there should be some equivalent counting logic, where the guessing competes against a line by line drawn hangman ...
Above code still needs replacement of input() by raw_input() when python v2 is being used ... but the OP used print() without future import, thus it is plausible, a Python v3 solution is good nuff.
Happy hacking!
So, the biggest issue was the scope of the continue_game variable. Since it was declared outside of the function. "while continue_game" always evaluates the same.
To fix, add global continue_game in the method definition.
below is code that will break out of the loop. to test I created a datas.txt file with one word and with the current logic, you have to type the word in that order for the str_found_letters != chosen_word to hit the else condition
import re
import random
folder = open("datas.txt","r")
data = folder.read()
word_list = re.sub("[^\w]"," ", data).split()
chosen_word = random.choice(word_list)
found_letters = []
continue_game = True
masked_word = []
for letter in chosen_word:
masked_word.append("*")
def guess_letter():
global continue_game, chosen_word, found_letters, masked_word
letter_player = raw_input('enter a letter pls: ')
for letter in range(0,len(chosen_word)):
if letter_player == chosen_word[letter]:
found_letters.append(letter_player)
masked_word[letter] = letter_player
else:
masked_word[letter] = '*'
print(masked_word[letter])
str_found_letters = ''.join(found_letters)
print(str_found_letters)
if(str_found_letters != chosen_word):
continue_game = True
else:
continue_game = False
while continue_game:
guess_letter()

'Answered' Python what is wrong with my if statement? (raw_input)

What I want to check for is if the user input is an empty string. I want the code to execute and output: "No input", however whenever I enter no input it goes to the next if statement and executes that with a blank value.
import urllib
import re
myString = " "
i = 0
def getStockPrice():
text_file = open("data.txt", "w")
url = "http://finance.yahoo.com/q?s=" + symbolslist
htmlfile = urllib.urlopen(url)
htmltext = htmlfile.read()
regex = '<span id="yfs_l84_' + symbolslist+ '">(.+?)</span>'
pattern = re.compile(regex)
price = re.findall(pattern,htmltext)
if str(price) == myString:
print "No input"
else:
print "the price of", symbolslist," is ", price
text_file.write(str(price))
text_file.close()
dino = raw_input("What stock would you like to Check?: ")
symbolslist = dino
getStockPrice()
while i < 1000:
lilly = raw_input("What other stocks do you want to check?: ")
symbolslist = lilly
getStockPrice()
"Empty string is the one which len(String) == 0. In your case len(MyString) == 1"_wanderlust2
This gave me some insight on the issue, it was very amateurish for me to make this mistake. Thanks!
In Python, an empty string evaluates to False. That means that you can use a simple code to improve your if statement:
user_input = raw_input("Stock to check")
user_input = user_input.strip() # be sure to clear any whitespace!
if user_input:
# continue on with your program
...
If you use this Python idiom, your code will be more concise and easier to read. If you get used to it, you'll understand other Python programs that use the feature too.
For your code, I would refactor what you have to something like this:
while True:
user_input = raw_input("Stock to check")
user_input = user_input.strip() # be sure to clear any whitespace!
if user_input:
if user_input.lower() == 'quit':
break
getStockPrice(user_input)
That would rely on you changing your getStockPrice function to accept an argument though! That's a simple change. Try adding an extra word within your parentheses:
def getStockPrice(symbolslist):

Checking Palindrome text, with ignored punctuation marks, spaces and case

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

Having trouble when replacing in a list-Python

I am having trouble replacing lists on python, my code is below.
def words_open():
global words
wordsfile = open("words.txt","r")
words_list = wordsfile.readlines()
words = []
for i in range(len(words_list)):
words.append(words_list[i].strip())
return words_list
return words
def replace_symbol_for_letter(letter,symbol):
print([s.replace(symbol,letter) for s in words])
return words
def enter_pairing():
correct_symbol = False
while correct_symbol == False:
symbol = input("Please enter a symbol: ")
if symbol not in symbols_list:
correct_symbol = False
elif symbol in symbols_list:
correct_symbol = True
correct_letter = False
while correct_letter == False:
letter = input("Please enter a letter: ")
letter = letter.upper()
if letter not in alphabet:
correct_letter = False
elif letter in alphabet:
correct_letter = True
current_pairings.append(symbol and letter)
replace_symbol_for_letter(letter,symbol)
return letter
return symbol
The code runs fine, without syntax errors, however I am having trouble replacing the 'words' list.
When I run the code this happens:
The words are:
#+/084&"
#3*#%#+
8%203:
,1$&
!-*%
.#7&33&
#*#71%
&-&641'2
#))85
9&330*
Please enter a symbol: #
Please enter a letter: A
['A+/084&"', 'A3*A%A+', '8%203:', ',1$&', '!-*%', '.A7&33&', 'A*A71%', "&-&641'2", 'A))85', '9&330*']
Please enter a symbol: +
Please enter a letter: b
['#B/084&"', '#3*#%#B', '8%203:', ',1$&', '!-*%', '.#7&33&', '#*#71%', "&-&641'2", '#))85', '9&330*']
As you can see the symbol is replaced to the letter, which works fine, however as soon as I enter a new symbol/letter pairing it deletes the previous replacement and the replaces it again.
Thanks!
In your code you don't modify the words list in replace_symbol_for_letter
print([s.replace(symbol,letter) for s in words])
This does not modify words list it just creates a new list having the pairing changed but words does not change
Replace it by this:
words = [s.replace(symbol,letter) for s in words]
print words
This should make it.
By the way: global vars are evil :)
You forgot to close your file avec reading it, you should consider to use the with statement to open your file, it will close it automaticly after your actions on it.
def words_open():
with open('words.txt', 'r') as file:
words_list = file.readlines()
words = [line.split() for line in words_list]
return words_list, words

Categories