Python: Trying to loop through a string to find matching characters - python-2.7

I am trying to create a simple "guess the word" game in Python. My output is something like:
String: _____ _____
Guess a word: 'e'
String:_e__o __e_e
Guess a word: 'h'
(and so on)
String: hello there
I have a function to do this, and within this function I have this code:
def guessing(word):
count = 0
blanks = "_" * len(word)
letters_used = "" #empty string
while count<len(word):
guess = raw_input("Guess a letter:")
blanks = list(blanks)
#Checks if guesses are valid
if len(guess) != 1:
print "Please guess only one letter at a time."
elif guess not in ("abcdefghijklmnopqrstuvwxyz "):
print "Please only guess letters!"
#Checks if guess is found in word
if guess in word and guess not in letters_used:
x = word.index(guess)
for x in blanks:
blanks[x] = guess
letters_used += guess
print ("".join(blanks))
print "Number of misses remaining:", len(word)-counter
print "There are", str(word.count(guess)) + str(guess)
guess is the raw input I get from the user for a guess, and letters_used is just a collection of guesses that the user has already input. What I'm trying to do is loop through blanks based on the word.index(guess). Unfortunately, this returns:
Guess a letter: e
e___
Yes, there are 1e
Help would be much appreciated!

Your code was almost correct. There were few mistakes which I have corrected:
def find_all(needle, haystack):
"""
Finds all occurances of the string `needle` in the string `haystack`
To be invoked like this - `list(find_all('l', 'hello'))` => #[2, 3]
"""
start = 0
while True:
start = haystack.find(needle, start)
if start == -1: return
yield start
start += 1
def guessing(word):
letters_uncovered_count = 0
blanks = "_" * len(word)
blanks = list(blanks)
letters_used = ""
while letters_uncovered_count < len(word):
guess = raw_input("Guess a letter:")
#Checks if guesses are valid
if len(guess) != 1:
print "Please guess only one letter at a time."
elif guess not in ("abcdefghijklmnopqrstuvwxyz"):
print "Please only guess letters!"
if guess in letters_used:
print("This character has already been guessed correctly before!")
continue
#Checks if guess is found in word
if guess in word:
guess_positions = list(find_all(guess, word))
for guess_position in guess_positions:
blanks[x] = guess
letters_uncovered_count += 1
letters_used += guess
print ("".join(blanks))
print "Number of misses remaining:", len(word)-letters_uncovered_count
print "There are", str(word.count(guess)) + str(guess)
else:
print("Wrong guess! Try again!")

Related

Skipping print but continuing program

So I have an assignment:
Your friend wants to try to make a word ladder! This is a list of words where each word has a one-letter difference from the word before it. Here’s an example:
cat
cot
cog
log
Write a program to help your friend.
It should do the following:
Ask your friend for an initial word
Repeatedly ask them for an index and a letter
You should replace the letter at the index they provided with the letter they enter You should then print the new word
Stop asking for input when the user enters -1 for the index
Here’s what should be happening behind the scenes:
You should have a function, get_index, that repeatedly asks the user for an index until they enter a valid integer that is within the acceptable range of indices for the initial string.
(If they enter a number out of range, you should reply invalid index.)
You should have another function, get_letter, that repeatedly asks the user for a letter until they enter exactly one lowercase letter. (If they enter more than one character, you should reply Must be exactly one character!. If they enter a capital letter, you should reply Character must be a lowercase letter!.)
You should store a list version of the current word in a variable. This is what you should update each time the user swaps out a new letter.
Each time you have to print the current word, print the string version of the list you are keeping in your variable.
I have tried rewriting, researching, and even debug mode.
def get_index():
while True:
index_in = int(input("Enter a number between 0 and " + str(len(string) - 1) + ": "))
if index_in > len(string) or index_in < -1:
print "Invalid Index"
elif index_in == -1:
return False
else:
get_letter(index_in)
def get_letter(index):
global string
char_list = list(string)
while True:
letter = input("Enter a letter: ")
if letter.isupper():
print "Character must be lower case!"
else:
char_list[index] = letter
string = ('').join(char_list)
break
print string
string = input("Enter a word: ")
get_index()
An example of the program should look like this:
Enter a word: cat
Enter an index (-1 to quit): 1
Enter a letter: o
cot
Enter an index (-1 to quit): 2
Enter a letter: g
cog
Enter an index (-1 to quit): 5
Invalid index
Enter an index (-1 to quit): -3
Invalid index
Enter an index (-1 to quit): 0
Enter a letter: L
Character must be a lowercase letter!
Enter a letter: l
log
Enter an index (-1 to quit): -1
Your code looks perfect!
Just need some changes according to (python 3)
def get_index():
while True:
index_in = int(input("Enter a number between 0 and " + str(len(string) - 1) + " (-1 to quit): "))
if index_in > len(string) -1 or index_in < -1:
print("Invalid Index")
elif index_in == -1:
return False
else:
get_letter(index_in)
def get_letter(index):
global string
char_list = list(string)
while True:
letter = input("Enter a letter: ")
if letter.isupper():
print("Character must be lower case!")
else:
char_list[index] = letter
string = ('').join(char_list)
break
print(string)
return
string = input("Enter a word: ")
get_index()
You should use print(msg) instead of print msg in python 3
You missed one condition, consider this scenario,
Run the program
Enter a word: c
Enter a number between 0 and 0 (-1 to quit): 1
Error
there was a wrong in get_index() check on line:
if index_in > len(string) or index_in < -1:
it should be :
if index_in > len(string) -1 or index_in < -1:
============================================================ *
UPDATE
updating the annwer according to discussion in comments:
def get_index(string):
try:
while True:
index_in = int(input("Enter a number between 0 and " + str(len(string) - 1) + " (-1 to quit): "))
if index_in > len(string) -1 or index_in < -1:
print("Invalid Index")
elif index_in == -1:
return False
else:
get_letter(index_in, string)
except ValueError:
print("Please Enter a number!")
get_index(string)
def get_letter(index, string):
char_list = list(string)
while True:
letter = input("Enter a letter: ")
if letter.isupper():
print("Character must be lower case!")
else:
char_list[index] = letter
string = ('').join(char_list)
break
print(string)
return
if __name__ == "__main__":
string = input("Enter a word: ")
get_index(string)
CHANGES are:
You must avoid global variables.
Instead, pass particular variable to functions as argumens.
Notice, how string was used in first answer and how it was used in the updated answer.
Use try-catch blocks to catch unexpected behavior

Really weird issue with CodeHS

I am doing some CodeHS for my computer science class at my school and for some reason my program doesnt meet the criteria of the grader, and maybe someone can assist me.
The autograder is looking for this:
The things it tests with are here:
and every result returns a runtime error in the autograder but not in the console.
Heres my code:
def get_letter():
while True:
letter = str(input("Enter a letter:\n> "))
if letter.isupper() == True:
print("Character must be a lowercase letter!")
continue
if len(letter) > 1 or len(letter) < 1:
print("Must be 1 character!")
elif letter.islower() == True:
return letter
break
def get_index():
while True:
try:
index = int(input("Enter an index (-1 to quit):\n> "))
if index == -1:
break
if index > len(word) or index < 0:
print "Invalid index"
continue
if index <= len(word):
global letter
letter = get_letter()
return index
break
except ValueError:
print "Please enter a number"
continue
word = input("Enter a word\n> ")
words = list(word)
while True:
try:
indexes = get_index()
splitword = words[:indexes] + [letter] + words[indexes +1:]
joinedword = ''.join(splitword)
print joinedword
except NameError:
break
and here are the instructions:
The CodeHS lesson is 8.3.8 Word Latter
This might be a little too late. I just came up to this question on CodeHS and had trouble myself. But I found it somewhere else, not to CodeHS's requirements so I had to fix it up myself. Here it is all fixed
def get_index(Inital_Word1):
User_Input = int(input("Enter an index (-1 to quit): "))
DexNav = len(Inital_Word1)
while User_Input > DexNav or User_Input<-1:
print "Invalid index"
User_Input = input("Enter an index (-1 to quit):")
DexNav = len(Inital_Word1)
return User_Input
def get_letter():
User_Input = input("Enter a letter: ")
DexNav = len(User_Input)
while DexNav > 1:
print "Must be exactly one character!"
User_Input = input("Enter a letter: ")
DexNav = len(User_Input)
while User_Input.isupper():
print "Character must be a lowercase letter!"
User_Input = input("Enter a letter: ")
return User_Input
def replace_at_index(User_Input, num, replacement):
return User_Input[0:num] + replacement + User_Input[num + 1:]
for i in range(1):
Inital_Word = input("Enter you inital word here: ")
Index = get_index(Inital_Word)
while Index != -1:
Letter = get_letter()
Inital_Word = replace_at_index(Inital_Word, Index, Letter)
print (Inital_Word)
Index = get_index(Inital_Word)

Converting python string to pig latin

def isAlpha(c):
return (ord(c) >= 65 and ord(c) <= 95) or \
(ord(c) >= 97 and ord(c) <= 122)
# testing first function
print isAlpha("D")
print isAlpha("z")
print isAlpha("!")
s = "AEIOUaeiou"
def isVowel(c):
return s.find(c) > -1
# testing second function
print isVowel("A")
print isVowel("B")
print isVowel("c")
print isVowel(" ")
print isVowel("a")
def convPigLatin_word(word):
if isVowel(word[0]):
word += "way"
while not isVowel(word[0]):
word = word[1:] + word[0]
if isVowel(word[0]):
word += "ay"
return word
# testing third function
print convPigLatin_word("This")
print convPigLatin_word("ayyyyyylmao")
def translate(phrase):
final = ""
while phrase.find(" ") != -1:
n = phrase.find(" ")
final += convPigLatin_word(phrase[0:n]) + " "
phrase = phrase[n+1:]
if phrase.find(" ") == -1:
final += convPigLatin_word(phrase)
return final
print translate("Hello, this is team Number Juan") #Should be "elloHay, isthay isway eamtay umberNay uanJay"
I tried to create a code that transform a string into pig latin. But I got stuck on the non-alphanumeric character. The while loop only works up to the comma. How can I resolve that? I don't know where to implement the isAlpha code to check for non alphanumeric character. Any advice is helpful.
You can iterate through the words of a phrase by using .split(' '). Then you can test them for special characters using .isalpha()
pigLatin = lambda word: word[1:]+ word[0]+"ay"
def testChars(word):
text = ""
for char in list(word):
if char.isalpha():
text += char
else:
return pigLatin(text)+ char
def testWords(lis):
words = []
lis = lis.split(' ')
for word in lis:
if not word.isalpha():
words.append( testChars(word) )
else:
words.append(pigLatin(word))
return (' ').join(words)
phrase = "I, have, lots of! special> characters;"
print testWords(phrase)

Python: The code disobeys the conditional depending on the input

I'm making a hang man game. When I made the code with out a conditional and classes, it worked fine. Basically my issues with the code below are:
Only the letter "t" will match. I can't get any other letter to match.
If I enter "t" on the first try, then purposely get the next 4 letters wrong, it won't end until after 7 turns. Yet if I enter any other letter first, it will end after 4 wrong turns, like it should.
My questions....
How can I get it to match with the other letters that are in the self.word index?
Why is it not obeying the condition I set with the while loop in the main method if I enter "t" on my first try and get every other letter wrong thereafter?
class Hang():
def __init__(self):
self.turns = 0
self.word = ['t', 'h', 'i', 's']
self.empty = ["__", "__", "__", "__"]
self.wrong = []
def main(self):
while self.turns < 4:
for i in self.word:
choice = raw_input("Enter a letter a-z: ")
if choice == i:
index = self.word.index(i)
self.empty.pop(index)
self.empty.insert(index, i)
print self.empty
else:
print "Wrong"
self.wrong.append(choice)
print self.wrong
print self.empty
self.turns += 1
char1 = Hang()
char1.main()
In the game of hangman you can guess any character in the phrase in any order. But you're using a for loop to go through each character in order and it is only correct if the player correctly guesses the characters in order
Try this instead
while self.turns < 4:
choice = raw_input("Enter a letter a-z: ")
# optional, if user enters more than a single letter
if len(choice) > 1:
print "invalid choice"
continue # loop again from start
index = self.word.index(choice)
if index != -1:
# -1 indicates character in not int the string
# so this block is only executed if character is
# in the string
self.empty[index] = choice # no need to pop, you can simply change the value of the list at a given index
else:
print "wrong"
self.turns += 1
print self.empty

Multiple Errors in Hangman program

I've been teaching my self to program in python lately and decided to make this game. I have been successful for the majority of it except for a few things
When an incorrect letter is inputted, the letter is appended to the wrong letter array for as many spots in the gamespace array that the userletter does equal.Example: if I type in "the" for the wordtarget, I get t, h and e printed 2 times into wrong letter array. No matter what the letter gets out into wrong letter array
Code:
wordTarget = raw_input("enter word here: ").lower ()
gameSpace = ["_"] * Len(wordTarget)
wrongLetter = []
def main():
for x in range(0, len(wordTarget)):
while (gameSpace[x] != wordTarget[x]):
getLetter()
for i in range(0,len(wordTarget)):
if (wordTarget[i] == userLetter):
gameSpace[i] = userLetter
elif (wordTarget[i] != userLetter):
print "letter is incorrect, try again"
wrongLetter.append(userLetter)
print ("Incorrect Letters: %s" % wrongLetter)
print ("Correct Letters: %s" % gameSpace)
if (gameSpace == wordTarget):
print "Congratulations! You won"
main()
I'm guessing the problem lies with the for loops I'm running and the way I'm checking for right answer but can't figure it out.
The loop checking the letter seems to be your issue. Try replacing it with:
position = 0
ptr = wordTarget.find(userLetter, position)
while ptr != -1:
gameSpace[ptr] = userLetter
position = ptr + 1
ptr = wordTarget.find(userLetter, position)
if position == 0: # no match ever found
print "letter is incorrect, try again"
wrongLetter.append(userLetter)
Also replace the original for loop with while ("".join(gameSpace) != wordTarget):, and you should be good to go.