How to replace the specified dash with the letter - python

I wish to write a hangman program and in order to do so, I have to replace the hash ('-') letter(s) with the user's guessed letter (guess). But when I run the code, it replaces all the hashes with the user's guess letter.
The code seems okay but I don't get the desired result.
words is a list of words I have written before the function.
def word_guess():
random.shuffle(words)
word = words[0]
words.pop(0)
print(word)
l_count = 0
for letter in word:
l_count += 1
# the hidden words are shown a '-'
blank = '-' * l_count
print(blank)
guess = input("please guess a letter ")
if guess in word:
# a list of the position of all the specified letters in the word
a = [i for i, letter in enumerate(word) if letter == guess]
for num in a:
blank_reformed = blank.replace(blank[num], guess)
print(blank_reformed)
word_guess()
e.g: when the word is 'funny', and guess is 'n', the output is 'nnnnn'.
How should I replace the desired hash string with guess letter?

it replaces all the hashes
This is exactly what blank.replace is supposed to do, though.
What you should do is replace that single character of the string. Since strings are immutable, you can't really do this. However, lists of strings are mutable, so you could do blank = ['-'] * l_count, which would be a list of dashes, and then modify blank[num]:
for num in a:
blank[num] = guess
print(blank)

A couple things to note:
inefficient/un-pythonic pop operation (see this)
l_count is just len(word)
un-pythonic, unreadable replacement
Instead, here's a better implementation:
def word_guess() -> str:
random.shuffle(words)
word = words.pop()
guess = input()
out = ''
for char in word:
if char == guess:
out.append(char)
else:
out.append('-')
return out

If you don't plan to use the locations of the correct guess later on, then you can simplify the last section of code:
word = 'hangman'
blank = '-------'
guess = 'a'
if guess in word:
blank_reformed = ''.join(guess if word[i] == guess else blank[i] for i in range(len(word)))
blank_reformed
'-a---a-'
(You still have some work to do make the overall game work...)

Related

Issue with analyzing strings in Python for Wordle-esque progam

I've created a function that takes a user-inputted guess, compared it to a hidden word taken randomly from a word doc, and returns a string that indicates if any letters match or are in the word at all. Here is the function:
def wordResults(guess, testGuess):
#guess = user inputted guess
#testGuess = secret word
results = ""
for i in range(5):
#Check if letters at given position match
#in each word, append capital letter if so
if guess[i] == testGuess[i]:
results += guess[i].upper()
#Check if letter at given position is in
#the secret word at all, append lowercase
#letter if so
elif testGuess.find(guess[i]) != -1:
results += guess[i]
#Append underscore if neither condition is met
else:
results += "_"
return results
My issue lies with the elif-statement. I would like it to print a lowercase only if that letter appears in the word, but not if the letter is already in the correct spot. Here is the program running to show what I'm referring to:
(Note: the hidden word is also user-inputted until I get the program working as intended)
For Guess #2, I would like it so that the first 'h' does not show up, since it is indicating the 5th letter in 'conch' that is already confirmed with a capital 'H'. Hope that makes sense.
It's a lot easier to work with a list and then make it a string at the end:
guess = guess.lower()
testGuess = testGuess.lower()
result = []
for i, letter in enumerate(guess):
if letter in testGuess:
if letter == testGuess[i]:
result.append(letter)
else:
result.append(letter.upper())
else:
result.append('_')
for i, letter in enumerate(result):
if letter.upper() in result and result[i] != letter:
result[i] = '_'
return ''.join(result)
For guess two, then the second loop checks if each letter is already in the loop and placed correctly and if it's not in the correct spot, makes it back into an _.

How to find words without certain letters in them and certain letters in the same place that are in specified length

I want to make a hangman game that randomises the word each time you guess a letter, but keeps the wrong letters wrong and the ones you guessed at the same place in the new word. (Like if your word was cat in the beginning and you guessed the 'a'; now the word can be hat.)
I feel like I want to implement too many statements in a while loop and it breaks somehow.
I have this function
def RevealLetters(inputLetter):
LetterPositons.clear()
global WrongGuessCounter
for pos,char in enumerate(Word):
if(char == inputLetter):
LetterPositons.append(pos)
for x in LetterPositons:
if MaskedWord[x] == "_":
MaskedWord[x] = inputLetter
if len(LetterPositons) == 0:
WrongGuessCounter += 1
WrongLetters.append(inputLetter)
Which adds the wrongly guessed letter to a list and those letters should not be used again.
Then in another function I have this while loop which should be able to go thru the list of words and select words that are a specified length (the length was set in another function)
def RandomiseWord():
global Word
print("Randomising Word!")
Word = random.choice(WordBank)
LetterPositons.clear()
while (len(Word) != len(MaskedWord)) and (all(letter in Word for letter in WrongLetters)) :
Word = random.choice(WordBank)
but this somehow gives me words that either contain a letter from the list or a word with a different length.
I tried using if statements inside the while but it broke it further.
And lastly how may I check for words that have the same letters in the same place?
The issue was in my while. it has to be the "Or" statement.
in the end the randomise function looked like this:
def RandomiseWord(): #Randomises the word to add a challange to the game
global Word
global MaskedWord
global WrongLetters
print("Randomising Word!")
Word = random.choice(WordBank)
LetterPositons.clear()
while len(Word) != (len(MaskedWord)+1) or all(letter in Word for letter in WrongLetters) or not all(CheckWord()) :
Word = random.choice(WordBank)
and for finding words with letters in the same place I used:
def CheckWord(): #checks if the word contains the letters in the same place as the hidden one
global MaskedWord
global Word
Match = []
LetterList = list(Word)
LetterList.pop()
for x in range(len(MaskedWord)):
if MaskedWord[x] == "_":
continue
elif MaskedWord[x] == LetterList[x]:
Match.append(True)
else:
Match.append(False)
return Match

Filter words in a sentence that begin with a certain range of letters

My task is to print all words in a sentence whose first letter is within a range of letters, for example: h-z.
This is my code so far, however it still prints words which begin with "g" and does not print the last word.
famous_quote = input("Enter a one sentence quote: ").lower()
word = ""
for ltr in famous_quote:
if ltr.isalpha() == True:
word = word + ltr
else:
if word > "g":
print(word)
word = ""
else:
word = ""
I'm only allowed to use ASCII comparisons, I've tried to compare the ASCII values but I don't know how to go about it in this context.
Sample input:
Wheresoever you go, go with all your heart
Sample output:
WHERESOEVER
YOU
WITH
YOUR
HEART
Algorithm I've come up with:
- split the words by building a placeholder variable: word
- Loop each character in the input string
- check if character is a letter
- add a letter to word each loop until a non-alpha char is encountered
- if character is alpha
- add character to word
- non-alpha detected (space, punctuation, digit,...) defines the end of a word and goes to else
- else
- check if word is greater than "g" alphabetically
- print word
- set word = empty string
- or else
- set word = empty string and build the next word
- Hint: use .lower()
You can define a neat little generator to split your sentence into words and compare the first letter of each.
def filter_words(sentence, lo, hi):
lo, hi = map(str.upper, (lo, hi))
words = sentence.upper().split()
for word in words:
if lo <= word[0] <= hi:
yield word
sentence = 'Wheresoever you go, go with all your heart'
print(*filter_words(sentence, 'h', 'z'), sep='\n')
WHERESOEVER
YOU
WITH
YOUR
HEART
This is how I approached this problem. It gave me a hard time since I am a beginer. But it seems to work fine.
quote = "quote goes here"
word = ""
for letter in quote:
if letter.isalpha():
word += letter
else:
if word > "":
print(word.upper())
word = ""
else:
word = ""
print(word.upper())
I added the space to the user_input and also used the word > 'h'. Below is how it looks:
user_input = input('Enter a phrase: ').lower()
user_input += ' '
word = ''
for char in user_input:
if char.isalpha():
word += char
else:
if word > 'h':
print(word.upper())
word = ''
else:
word = ''
This code worked for me...
The task is: Create a program inputs a phrase (like a famous quotation) and prints all of the words that start with h-z
I was making the mistake of using word > "g" before, which needs to be replaced by word > "h".
Also, you need to add the last print command in order to print the last word in case the phrase does not end with a punctuation (as in the given example)
phrase = input ("Please enter a phrase: ").lower()
word = ""
for letter in phrase:
if letter.isalpha():
word += letter
else:
if(word > "h" ):
print(word)
word = ""
else:
word = ""
if word.lower() > 'h':
print(word)
Just one comment on the exercise, as a programming exercise this approach is fine but you would never do it this way in practice.
The two issues you've highlighted is that you are comparing the whole word instead of just the first character.
Simply change:
if word > "g":
To:
if word and word[0] > "g":
And if the quote doesn't finish with a punctuation you will miss the last word off, just add after the loop:
if word:
print(word)
You may note the output is all uppercase, so .lower() the whole quotation may be an issue, alternatively you can just .lower() the comparison, e.g.:
famous_quote = input("Enter a one sentence quote: ")
...
if word and word[0].lower() > "g":
Note: You can simplify your else: condition:
else:
if word and word[0] > "g":
print(word)
word = ""
You stated that you are not allowed to use the split() method. I am not sure what you can use, so here's a solution (not the optimal one).
famous_quote = input("Enter a one sentence quote:") + ' '
current_word = None
for c in famous_quote:
if ('a' <= c <= 'z') or ('A' <= c <= 'Z'):
if current_word is None:
current_word = c # start a new word
else:
current_word += c # append a new letter to current word
else:
if current_word is not None:
f = current_word[0] # first letter
if ('h' <= f <= 'z') or ('H' <= f <= 'Z'):
print(current_word)
current_word = None
Here is a sample run of the program. It preserves lowercase and uppercase. It also splits words on any non-ASCII character.
Enter a one sentence quote: Whereever you go, there you are!!!
Whereever
you
there
you
Note: Since printing is done when a non-ASCII character is encountered, a non-ASCII character is appended at the end of famous_quote.
Assuming that the famous quote contains only spaces as word separator, this should do the job:
words = input("Enter a one sentence quote: ").lower().split()
for word in words:
if word[0] > 'g':
print("{w} ".format(w = word))
split() transforms a string into a list (array). It takes, by default, the space character as parameter (hence I did not give the argument) and returns the list of words.
print() can be used in a lot of ways, due to python's history with this function.
You can .join() the list (getting a string as result) and print it:
print(" ".join(words))
you can also print with concatenations (considered ugly):
print(word+" ")
or you can use formatted printing, which I do use a lot for readibility:
print("{w} ".format(w = word))
interprets "{w}" and replaces it with word wherever "{w}" appears.
Print formatting is rather CPU consuming (but it is still really fast). Usually any print operation slows your application, you want to minimize making outputs if you are making CPU intensive apps in your future (here I don't do that because CPU is not the main concern).
1. Split the words by building a placeholder variable: word
Loop each character in the input string
and check if character is a letter. Then add letter to the variable "word". Loop until a non-alpha char is encountered.
2. If character is alpha or (alphabet)
Add character to word.
Non-alpha detected (space, punctuation, digit,...) defines the end of a word and goes to the "else" part.
input_quote = input("Enter a 1 sentence quote, non - alpha seperate words: ")
word = ""
for character in input_quote:
if character.isalpha():
word += character
3. Else
Check if word is greater than "g" alphabetically. Print word and set "word = empty" string.
else:
if word and word[0].lower() >= "h":
print("\n", word.upper())
word = ""
4. Or else
Set word = empty string and build the next word.
else:
word = ""
if word.lower() >= "h":
print("\n", word.upper())
The last "if" is explicitly coded to print the last word if it doesn't end with a non-alpha character like a space or punctuation.
I did this exact same problem. The issue most people are having (and no one seemed to point out) is when you encounter double punctuations or a punctuation followed by a space.
This is the code I used.
phrase = input("Please enter a famous quote: ")
word = ""
for letter in phrase:
if letter.isalpha() is True:
word += letter
elif len(word) < 1: <--- [This is what accounts for double punctuations]
word = ""
elif word[0].lower() >= "g":
print(word)
word = ""
else:
word = ""
print(word) <--- [accounts for last word if not punctuated]
Variable "word" already contains your last word of the phrase but since it does not fulfil the condition to enter the loop it does not gets printed. So you can check the below solution.
phrase = input("Enter a phrase after this: ")
word = ""
for char in phrase:
if char.isalpha():
word += char
else:
if word != "":
if word[0].lower() >= "h":
print(word.upper())
word = ""
else:
word = ""
if word[0].lower() >= "h":
print(word.upper())
This code works for me:
phrase=input("Enter a one sentence quote,non-alpha separate words: ")
word=""
for character in phrase:
if character.isalpha():
word+=character
else:
if word.lower()>="h".lower():
print(word.upper())
word="" -----this code defines the end of a word
else:
word=""
print(word.upper()) ------this will print the last word
I would use regular expressions and list compreshension as shown in the function below.
def words_fromH2Z():
text = input('Enter a quote you love : ')
return [word for word in re.findall('\w+', text) if not word[0] in list('aAbBcCdDeEfFgG')]
When I test the function by putting in the input "I always Visit stack Overflow for Help", I get:
words_fromH2Z()
Enter a quote you love : I always Visit stack Overflow for Help
['I', 'Visit', 'stack', 'Overflow', 'Help']
This worked well for me. I had to add the last two lines of code because without them, it wasn't printing the last word, even if it began with a letter between h and z.
word = ""
quote = input("Enter your quote")
for char in quote:
if char.isalpha():
word += char
elif word[0:1].lower() > "g":
print(word.upper())
word = ""
else:
word = ""
if word[0:1].lower() > "g":
print(word.upper())
famous_quote = input("Enter a one sentence quote:")
current_word = None
for c in famous_quote:
if c.isalpha():
if (c >= 'a') or (c >= 'A'):
if current_word is None:
current_word = c
else:
current_word += c
else:
if current_word is not None:
f = current_word[0]
if ('h' <= f <= 'z') or ('H' <= f <= 'Z'):
print (current_word.upper())
current_word = None
if famous_quote[-1].isalpha():
print (current_word.upper())

Randomize letters in a word

the question asks to have to user enter a one word string, then randomize the place of the letters in the word, for example, "hello" can turn into "elhlo"
import random
def word_jumble():
word = raw_input("Enter a word: ")
new_word = ""
for ch in range(len(word)):
r = random.randint(0,len(word)-1)
new_word += word[r]
word = word.replace(word[r],"",1)
print new_word
def main():
word_jumble()
main()
I got the program from someone else, but have no idea how it works. can someone explain to me please? I understand everything before
new_word += word[r]
The code is unnecessarily complex, maybe this will be easier to understand:
import random
word = raw_input("Enter a word: ")
charlst = list(word) # convert the string into a list of characters
random.shuffle(charlst) # shuffle the list of characters randomly
new_word = ''.join(charlst) # convert the list of characters back into a string
r is a randomly selected index in the word, so word[r] is a randomly selected character in the word. What the code does is it selects a random character from word and appends it to new_word (new_word += word[r]). The next line removes the character from the original word.
If you use a bytearray, you can use random.shuffle directly
import random
word = bytearray(raw_input("Enter a word: "))
random.shuffle(word)

Why do I get a "string index out of range" error with letter variable above while word: statement but not below?

Below is some code from a game I am creating which scrambles the letters of a random word for a player to guess. I was wondering why when I put my letter variable (which assigns a random letter from one of the words in my word bank to the variable letter) above my while word: statement there is a string index error but if I put the same variable in the while word: statement there is no error.
I know that in the string koala, for example, k is 0 and a is 4. Why would that change within the while statement? Or is there something else going on?
This works:
while word:
letter = random.randrange(len(word))
scrambled_word += word[letter]
word = word[:letter] + word[(letter+1):]
This does not work:
scrambled_word = ''
letter = random.randrange(len(word))
while word:
scrambled_word += word[letter]
word = word[:letter] + word[(letter+1):]
Why?
With each iteration of
while word:
scrambled_word += word[letter]
word = word[:letter] + word[(letter+1):]
word is shortened by one letter:
>>> "koala"[:3]
'koa'
>>> "koala"[4:]
'a'
so eventually word[letter] will try to access a letter that's no longer there.
If you want to scramble a word, there's a built-in function for that, though:
>>> word = "koala"
>>> l = list(word)
>>> random.shuffle(l)
>>> word = "".join(l)
>>> word
'oklaa'
(taking a detour via a list object because strings themselves are immutable and can't be shuffled directly).
I'm not a python programmer, but this is probably wrong:
word = word[:letter] + word[(letter+1):]
You need to check if the letter is the last one, otherwise word[(letter+1):] is out of bound.

Categories

Resources