Multiple Errors in Hangman program - python-2.7

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.

Related

Repeat a function every 5 times a loop runs

Is there a way to repeat a single function in a while loop one in every 5 times the loop runs? I am trying to create a bot to help me with my Latin revision but I don't want the option to close the program to crop up every time I answer a question, it would be better if it only happened 1 out of 10 times.
import random
exit = "no"
print "welcome to latin learner v1"
wordtype = raw_input("what would you like to learn (nouns verbs everything)")
if wordtype == "nouns":
declension = raw_input("declension 1-5")
if declension == "1":
while "no" in exit:
wordno = random.randint(1,30)
noun1L = ["ancilla","aqua","cena","copiae","cura","dea","domina","epistula","femina","filia","hora","ianua","insula","ira","nauta","patria","pecunia","poena","porta","puella","regina","Roma","silva","taberna","terra","turba","via","victoria","villa","vita"]
answer = raw_input(noun1L[wordno])
noun1E = ["slave-girl" or"slave-woman","water","dinner" or "meal","forces" or "troops","care" or "worry","goddess","mistress","letter","woman","daughter","hour","door","island" or "block of flats","anger","sailor","country" or "homeland","money","punishment","gate","girl","queen","Rome","wood","shop" or "inn","ground" or "land" or "country","crowd","street" or "road" or "way","victory","house" or "country villa","life"]
if noun1E[wordno] == answer:
print "correct"
else:
print "incorrect"
print noun1E[wordno]
for i in range[1,5]:
exit = raw_input("would you like to quit (yes/no)")
To solve your issue, we can add a question counter and use the modulus operator (%) to trigger the exit option on every fifth question.
However, there are some other problems to address. For example, this:
,"dinner" or "meal",
is just wishful thinking -- it doesn't work that way. We can turn this into a list of possible answers. Next, whenever we have parallel arrays like noun1L and noun1E, it usually means we're missing a data structure. Finally, don't store the data in the code, separate them.
Here's my rework of your code addressing the above issues:
import random
noun1 = {
"ancilla": ["slave-girl", "slave-woman"],
"aqua": ["water"],
"cena": ["dinner", "meal"],
"copiae": ["forces", "troops"],
"cura": ["care", "worry"],
"dea": ["goddess"],
"domina": ["mistress"],
"epistula": ["letter"],
"femina": ["woman"],
"filia": ["daughter"],
"hora": ["hour"],
"ianua": ["door"],
"insula": ["island", "block of flats"],
"ira": ["anger"],
"nauta": ["sailor"],
"patria": ["country", "homeland"],
"pecunia": ["money"],
"poena": ["punishment"],
"porta": ["gate"],
"puella": ["girl"],
"regina": ["queen"],
"Roma": ["Rome"],
"silva": ["wood"],
"taberna": ["shop", "inn"],
"terra": ["ground", "land", "country"],
"turba": ["crowd"],
"via": ["street", "road", "way"],
"victoria": ["victory"],
"villa": ["house", "country villa"],
"vita": ["life"],
}
print("Welcome to Latin Learner v1")
wordtype = raw_input("What would you like to learn (nouns verbs everything): ")
if wordtype == "nouns" or wordtype == "everything":
declension = raw_input("Declension 1-5: ")
if declension == "1":
count = 1
while True:
word = random.choice(list(noun1))
answer = raw_input(word +": ")
if answer.lower() in noun1[word]:
print("Correct.")
else:
print("Incorrect: " + ", ".join(noun1[word]))
if count % 5 == 0:
answer = raw_input("would you like to quit (yes/no): ")
if "y" in answer.lower():
break
count += 1

Python: Trying to loop through a string to find matching characters

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!")

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

Printing out values from a function

Ok so the issue with my program is that for some reason when I run it the variables at the bottom come out as "None" instead of the count of the amount of ATG's in the original strings of HumanDNA, MouseDNA, and UnknownDNA. I couldn't add the part where i define these DNA's because of their length and was difficult for me to add it. How can I change it so instead it outputs the amount of times the substring is found in the original string as a variable that is outside the function and can output it in the format I have at the bottom.
def countCodon(string, substring):
i = string.find(substring)
def compareDNA(string1, string2):
string1 = raw_input("Enter string 1: ")
string2 = raw_input("Enter string 2: ")
Hamming = 0
for ch1, ch2 in zip(string1, string2):
if ch1 != ch2:
Hamming += 1
l = len(string1)
similarity_score = ((l - Hamming)/(l))
print similarity_score
HD = countCodon(humanDNA, "ATG")
MD = countCodon(mouseDNA, "ATG")
UD = countCodon(unknownDNA, "ATG")
print "Mouse: ", HD
print "Human: ", MD
print "Unknown: ", UD
MU = compareDNA(mouseDNA, unknownDNA)
HU = compareDNA(humanDNA, unknownDNA)
if MU != HU and MU > HU:
print "mouse"
elif MU != HU and MU < HU:
print "human"
elif MU == HU:
print "identity cannot be determined"
EDIT: Added the messed up part of the second function running into a similar problem.
countCodon() has no return value so HD = None
Moreover from https://docs.python.org/2/library/string.html
string.find(s, sub[, start[, end]])
Return the lowest index in s where the substring sub is found such that sub is wholly contained in s[start:end]. Return -1 on failure. Defaults for start and end and interpretation of negative values is the same as for slices.
So countCodon() is giving you the index where the string "ATG" first appears, not the number of times it is present.

how to loop a set amount of times

Im writing a code that simulates the game word scrabble. What im trying to do is that it asks the user to unscrabble the word, and if they fail at it once they get another chance and so on for 3 chances. after 3 chances the program should tell them that they couldn't guess it within the chances limit and the program should tell them the word.
rand_artist = artist_names[random.randrange(len(artist_names))]
tries = 0
while tries < 3:
rand_input = enterbox("Unscrabble the following: {}".
format(txt), "Word Scrabble")
if rand_input != rand_artist:
msgbox("Try again!", "Word Scrabble")
tries +=1
elif rand_input == rand_artist:
msgbox("Congratulations! You guessed the word!")
tries +=3
elif tries > 2:
msgbox("You used up three chances! The word was {}".
format(txt), "Word Scrabble!")
Your code had several problems, some noted in my comment on the question. The following works as you seem to want.
from random import choice, shuffle
artist_names = ['Renoir', 'VanGogh', 'Rembrant', 'Homer', 'Pyle',]
artist = choice(artist_names)
alist = list(artist)
shuffle(alist)
scram = ''.join(alist)
for tries in range(1, 4):
guess = input("Unscrabble {}: ".format(scram))
if guess == artist:
print("Congratulations! You guessed the word!")
break
elif tries < 3:
print("Try again!")
else:
print("Failed three chances! The word was {}.".format(artist))