I am making a hangman game, but there's something i can't figure out.
I am able to hide the letters using
guessed = "_"*len(guess)
but it also hides the spaces. for example if my word is 'the avengers' it will hide 12 characters instead of 11. how do unhide/leave the spaces alone? this is what i have so far:
def getHiddenWord():
guess = getRandomWord().lower()
guessed = "_"*len(guess)
if "_" in guessed is " ":
print(guessed.replace("_", " "))
else:
print("The Word is:", guessed)
return guessed
Use re.sub
guessed = re.sub(r'\S', '_', guess)
\S would match any non-space character. So the above re.sub function would replace any non-space character from the input string with _.
Example:
>>> import re
>>> s = 'the avengers'
>>> re.sub(r'\S', '_', s)
'___ ________'
>>>
or
>>> ''.join(['_' if not i.isspace() else i for i in s])
'___ ________'
>>>
A simple way to do that:
def getHiddenWord(guess):
guessed = ''
for c in guess.lower():
if c != ' ':
guessed += '_'
else:
guessed += ' '
return guessed
The problem with your approach is that you use this:
guessed = "_"*len(guess)
It takes the whole length of the string and the empty space is also counted. If for some reason you need to exclude empty space in the count of len you need to use this:
guessed = "_" * (len(guess) - guess.count(' '))
But in your case you most likely don't need it.
Also note that the function getHiddenWord(guess) does not change your original word but creates a new one and returns it.
Related
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...)
I'm writing a hangman game in python for class. The user is told they have guessed incorrectly when they put a lower case when it is upper case and vice versa. Also when there is a space in the input it displays as an underscore (_) as well.
def gettingWord(theWord, lettersGuessed):
count = 0
blank = ['_ '] * len(theWord)
for i, c in enumerate(theWord):
if c in lettersGuessed:
count = count + 1
blank.insert(count-1,c)
blank.pop(count)
if count == len(theWord):
return ''.join(str(e) for e in blank)
else:
count = count + 1
blank.insert(count-1,'_')
blank.pop(count)
if count == len(theWord):
return ''.join(str(e) for e in blank)
The code itself works I just want to know how I can fix this issue. Can anyone help?
If I'm understanding correctly you want the user to be able to use uppercase and lowercase characters without affecting the result. If that's the case then you can use string's method lower() in order to turn each character the user guesses lowercase. In your function you could just add these two lines in the beginning:
theWord = theWord.lower()
lettersGuessed = [c.lower() for c in lettersGuessed]
First you turn the word to guess into lowercase, and then you turn each character in lettersGuessed lowercase (assuming lettersGuessed is a list of characters, if it's a string then you can just write lettersGuessed = lettersGuessed.lower()). This way all characters will be lowercase so the answer will depend on the character only and not on the casing.
Convert both the character and the letters guessed to lowercase to ignore case. If the character is whitespace, you also want to insert the character so you should add or not c.strip() to the if check to also insert the character if its whitespace.
Also, just to reduce code duplication, you should try and remove the duplicate code out of the if/else blocks, this will help with maintaining this or changing the logic in the future.
def gettingWord(theWord, lettersGuessed):
count = 0
blank = ['_ '] * len(theWord)
for c in theWord:
if c.lower() in lettersGuessed.lower() or not c.strip():
blank.insert(count, c)
else:
blank.insert(count, '_')
count = count + 1
blank.pop(count)
if count == len(theWord):
return ''.join(str(e) for e in blank)
Convert everything to lowercase, and strip spaces.
All the words in the word bank should be lowercase
When getting input:
letter = input('Enter a letter: ').lower().strip()
That should fix your problems with spaces and casing.
This question already has answers here:
How can I print multiple things on the same line, one at a time?
(18 answers)
Closed last month.
I'm new to coding, and I found this exercise problem in a Python practice website. The instructions go like this:
"Write a function translate() that will translate a text into "rövarspråket" (Swedish for "robber's language"). That is, double every consonant and place an occurrence of "o" in between. For example, translate("this is fun") should return the string "tothohisos isos fofunon".
So I inputted this code:
def translate(string):
vowels=['a','e','i','o','u']
for letter in string:
if letter in vowels:
print(letter)
else:
print(letter+'o'+letter)
print(translate('this is fun'))
and I got this:
tot
hoh
i
sos
o
i
sos
o
fof
u
non
None
So how do I put all these strings in one line? I've been scratching my head for so long. Please help and thank you:)
You can concatenate the strings iteratively. You should include a whitespace as part of the characters to exclude to avoid putting an 'o' in between whitespaces.
def translate(string):
notconsonant = ['a','e','i','o','u', ' ']
s = ''
for letter in string:
if letter in notconsonant:
s += letter
else:
s += letter+'o'+letter
return s
Or use join with a generator expression that returns the right letter combination via a ternary operator:
def translate(string):
notconsonant = {'a','e','i','o','u', ' '}
return ''.join(letter if letter in notconsonant else letter+'o'+letter for letter in string)
Note that you can speed up the lookup of letters that are not consonants if you made the list a set, as membership check for sets is relatively faster.
>>> translate('this is fun')
'tothohisos isos fofunon'
Just use the end parameter in print function. (I assumed that you are using python 3.x, with print being a function)
def translate(string):
vowels=['a','e','i','o','u']
for letter in string:
if letter in vowels:
print(letter, end='')
else:
print(letter+'o'+letter, end='')
print(translate('this is fun'))
Try to append it in a temporary string and to print it at the end ;)
print get's you to a new line. Use a concatenation and a new string instead (here the new string is called result) :
def translate(string):
vowels=['a','e','i','o','u']
# Use a new variable :
result = ''
for letter in string:
if letter in vowels:
result = result + letter
else:
result = result + letter + 'o' + letter
return result
print(translate('this is fun'))
def main():
print('Please enter a sentence without spaces and each word has ' + \
'a capital letter.')
sentence = input('Enter your sentence: ')
for ch in sentence:
if ch.isupper():
capital = ch
sentence = sentence.replace(capital, ' ' + capital)
main()
Ex: sentence = 'ExampleSentenceGoesHere'
I need this to print as: Example sentence goes here
as of right now, it prints as: Example Sentence Goes Here (with space at the beginning)
You can iterate over the string character by character and replace every upper case letter with a space and appropriate lower case letter:
>>> s = 'ExampleSentenceGoesHere'
>>> "".join(' ' + i.lower() if i.isupper() else i for i in s).strip().capitalize()
'Example sentence goes here'
Note that check if the string is in upper case is done by isupper(). Calling strip() and capitalize() just helps to deal with the first letter.
Also see relevant threads:
Elegant Python function to convert CamelCase to snake_case?
How to check if a character is upper-case in Python?
You need to convert the each uppercase letter to a lowercase one using capital.lower(). You should also ignore the first letter of the sentence so it stays capitalised and doesn't have a space first. You can do this using a flag as such:
is_first_letter = True
for ch in sentence:
if is_first_letter:
is_first_letter = False
continue
if ch.isupper():
capital = ch
sentence = sentence.replace(capital, ' ' + capital.lower())
I'd probably use re and re.split("[A-Z]", text) but I'm assuming you can't do that because this looks like homework. How about:
def main():
text = input(">>")
newtext = ""
for character in text:
if character.isupper():
ch = " " + character.lower()
else:
ch = character
newtext += ch
text = text[0]+newtext[2:]
You could also do:
transdict = {letter:" "+letter.lower() for letter in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'}
transtable = str.maketrans(transdict)
text.translate(transtable).strip().capitalize()
But again I think that's outside the scope of the assignment
I want the letters the user types (granted that they're in the 'letters') to replace the blanks in their correct sequential position (I don't want 'agbdf__'), and stop when all the letters are typed in. As the code is now, it requires letters to be typed multiple times, and it stops if the letter 'g' is typed seven times. This is a part of a hangman code I'm trying to implement. If anyone could post the right way to program this (not just a tip, because I most likely won't be able to figure out how to implement it), it would be much appreciated.
letters='abcdefg'
blanks='_'*len(letters)
print('type letters from a to g')
print(blanks)
for i in range(len(letters)):
if letters[i] in input():
blanks = blanks[:i] + letters[i] + blanks[i+1:]
print(blanks)
Change your loop to:
for i in range(len(letters)):
letter = raw_input()
index = letters.index(letter)
blanks = blanks[:index] + letter + blanks[index + 1:]
print blanks
You are not replacing the correct blank/underscore, you are just sequentially replacing them. Instead you need to find the correct blank to replace, and then replace that. Also don't expect this code to be running infinitely until the blanks is completely filled. If you want that, you can figure that out I guess (as your question is specific to replacing correct letters). Also you might want this program should handle inputs other than 'abcdef' too :).
You could use a list comprehension for this. Here's an example:
letters = 'abcdefg'
typed = raw_input('Type the characters a through g: ')
print ''.join(s if s in typed else '_' for s in letters)
Sample Output:
Type the characters a through g: abdef
ab_def_
Here's a more complete/advanced hangman example: https://gist.github.com/dbowring/6419866
letters = 'abcdefg'
print('type letters from a to g')
all_letters = list(letters)
blanks = ['_'] * len(letters)
while True:
guessed_letter = input("guess > ")
while guessed_letter in all_letters:
index = all_letters.index(guessed_letter)
all_letters[index] = None
blanks[index] = guessed_letter
output = ''.join(blanks)
print(output)
if letters == output:
print("gg")
break
Or if you prefere a more stringy version
letters = 'abcdefg'
print('type letters from a to g')
all_letters = list(letters)
blanks = '_' * len(letters)
while True:
guessed_letter = input("guess > ")
while guessed_letter in all_letters:
index = all_letters.index(guessed_letter)
all_letters[index] = None
blanks = blanks[:index] + guessed_letter + blanks[index+1:]
print(blanks)
if letters == blanks:
print("gg")
break