Hangman - duplicate char - python-2.7

I have one question regarding this hangman program of mine.When I guess the a letter('o') right of a word("good") which has duplicates,it's being unveiled only for the first index as list.index(value) returns only one index even if there are duplicates of that value.What do I need to change or add if I want to unveil all the duplicate letters at the same time.
Here's what I Expect the program to do:
Guess the letter: l >>> _oo_
Thanks.
the_word="good"
#print the_word
wLen=len(the_word)
u='_'*wLen
counter=0
while counter!=12 and wLen!=0:
counter=counter+1
print u
g=raw_input("Guess the letter: ")
p=list(the_word)
x1=the_word.find(g)
if x1 >=0:
u1=list(u)
u1[x1]=g
u=''.join(u1)
wLen=wLen-1
if wLen==0:
print "Congratulation!!!you have guessed the word"
print "The word was",the_word
else:
print "sorry u loose"

In case this is for an assignment, I'll focus on a simpler solution that will hopefully make sense. You know your target word, and from that you can use a function called enumerate to find the index positions of all of the letters:
In [31]: word = 'good'
In [32]: for index, letter in enumerate(word):
....: print index, letter
....:
0 g
1 o
2 o
3 d
So knowing this, let's say a user inputs o. Our current 'guessing' string looks like ____, and we know that we need to replace index positions 1 and 2 with o. Since the guess string and the target word have the same length (since they are supposed to be the same word), one simple solution would be to iterate over the actual word with enumerate, and if the letter is o (or whatever they guessed), replace the same index position in the guessing word with that letter. For example:
In [33]: word = 'good'
In [34]: guess_list = list('_' * len(word))
In [35]: g = raw_input('Guess a letter: ')
Guess a letter: o
In [36]: for index, letter in enumerate(word):
....: if letter == g:
....: guess_list[index] = letter
....:
In [37]: print ''.join(guess_list)
_oo_

while (true):
x1=the_word.find(g)
if x1 < 0:
break
u1=list(u)
u1[x1]=g
u=''.join(u1)
wLen=wLen-1
Something like this should work. Haven't tested it, but that should be the correct logic.

Related

how to not remove space in file

how to keep the space betwen the words?
in the code it deletes them and prints them in column.. so how to print them in row and with the space?
s ='[]'
f = open('q4.txt', "r")
for line in f:
for word in line:
b = word.strip()
c = list(b)
for j in b:
if ord(j) == 32:
print ord(33)
if ord(j) == 97:
print ord(123)
if ord(j) == 65:
print ord(91)
chr_nums = chr(ord(j) - 1)
print chr_nums
f.close()
Short answer: remove the word.strip() command - that's deleting the space. Then put a comma after the print operation to prevent a newline: print chr_nums,
There are several problems with your code aside from what you ask about here:
ord() takes a string (character) not an int, so ord(33) will fail.
for word in line: will be iterating over characters, not words, so word will be a single character and for j in b is unnecessary.
Take a look at the first for loop :
for line in f:
here the variable named 'line' is actually a line from the text file you are reading. So this 'line' variable is actually a string. Now take a look at the second for loop :
for word in line:
Here you are using a for loop on a string variable named as 'line' which we have got from the previous loop. So in the variable named 'word' you are not going to get a word, but single characters one by one. Let me demonstrate this using a simple example :
for word in "how are you?":
print(word)
The output of this code will be as follows :
h
o
w
a
r
e
y
o
u
?
You are getting individual characters from the line and so you don't need to use another for loop like you did 'for j in b:'. I hope this helped you.

Python - Obtain the most frequent word in a sentence, if there is a tie return the word that appears first in alphabetical order

I have written the following code below. It works without errors, the problem that I am facing is that if there are 2 words in a sentence that have been repeated the same number of times, the code does not return the first word in alphabetical order. Can anyone please suggest any alternatives? This code is going to be evaluated in Python 2.7.
"""Quiz: Most Frequent Word"""
def most_frequent(s):
"""Return the most frequently occuring word in s."""
""" Step 1 - The following assumptions have been made:
- Space is the default delimiter
- There are no other punctuation marks that need removing
- Convert all letters into lower case"""
word_list_array = s.split()
"""Step 2 - sort the list alphabetically"""
word_sort = sorted(word_list_array, key=str.lower)
"""Step 3 - count the number of times word has been repeated in the word_sort array.
create another array containing the word and the frequency in which it is repeated"""
wordfreq = []
freq_wordsort = []
for w in word_sort:
wordfreq.append(word_sort.count(w))
freq_wordsort = zip(wordfreq, word_sort)
"""Step 4 - output the array having the maximum first index variable and output the word in that array"""
max_word = max(freq_wordsort)
word = max_word[-1]
result = word
return result
def test_run():
"""Test most_frequent() with some inputs."""
print most_frequent("london bridge is falling down falling down falling down london bridge is falling down my fair lady") # output: 'bridge'
print most_frequent("betty bought a bit of butter but the butter was bitter") # output: 'butter'
if __name__ == '__main__':
test_run()
Without messing too much around with your code, I find that a good solution can be achieved through the use of the index method.
After having found the word with the highest frequency (max_word), you simply call the index method on wordfreq providing max_word as input, which returns its position in the list; then you return the word associated to this index in word_sort.
Code example is below (I removed the zip function as it is not needed anymore, and added two simpler examples):
"""Quiz: Most Frequent Word"""
def most_frequent(s):
"""Return the most frequently occuring word in s."""
""" Step 1 - The following assumptions have been made:
- Space is the default delimiter
- There are no other punctuation marks that need removing
- Convert all letters into lower case"""
word_list_array = s.split()
"""Step 2 - sort the list alphabetically"""
word_sort = sorted(word_list_array, key=str.lower)
"""Step 3 - count the number of times word has been repeated in the word_sort array.
create another array containing the word and the frequency in which it is repeated"""
wordfreq = []
# freq_wordsort = []
for w in word_sort:
wordfreq.append(word_sort.count(w))
# freq_wordsort = zip(wordfreq, word_sort)
"""Step 4 - output the array having the maximum first index variable and output the word in that array"""
max_word = max(wordfreq)
word = word_sort[wordfreq.index(max_word)] # <--- solution!
result = word
return result
def test_run():
"""Test most_frequent() with some inputs."""
print(most_frequent("london bridge is falling down falling down falling down london bridge is falling down my fair lady")) # output: 'down'
print(most_frequent("betty bought a bit of butter but the butter was bitter")) # output: 'butter'
print(most_frequent("a a a a b b b b")) #output: 'a'
print(most_frequent("z z j j z j z j")) #output: 'j'
if __name__ == '__main__':
test_run()

Python Iterating through a string to look for a Palindrome

So I have looked around this site and others for information on how to iterate through a string on Python, find a specific substring, reverse it and check if the two equaled in order to get a Palindrome. This is the problem though since some of the test cases are challenging to get and have confused me on how to find them through indexing.
This is my code that works for all, but two test cases:
def countPalindromes(s):
count = 0
firstindex = 0
lastindex = len(str)-1
while firstindex != lastindex and firstindex <= lastindex:
ch1 = s[firstindex:lastindex]
ch2 = s[lastindex:firstindex:-1]
if ch1 == ch2:
count +=1
firstindex +=1
lastindex -=1
return count
This code works for the following Palindromes: "racecar", " ", and "abqc".
It does not work for these Palindromes "aaaa" and "abacccaba".
For "aaaa" there are 6 palindromes and for "abacccaba" there are 8 palindromes. This is where my problem occurs, and I simply can't figure it out. For the 6 palindromes for "aaaa" I get aaaa, aaa, aa, twice for each. For "abacccaba" the 8 palindromes I have no idea as I get abacccaba, bacccab, accca, ccc, aba, aba.
I understand this is a confusing question, but I am lost how to approach the problem since I only get 2 for the "aaaa" and 4 for "abacccaba". Any ideas how I would cut out the substrings and get these values?
Thanks in advance!
while firstindex != lastindex and firstindex <= lastindex: misses the case of a single character palindrome.
You're also missing the case where aa contains three palindromes, 0:1, 0:2 and 1:2.
I think you're missing some palindromes for aaaa; there are 10:
aaaa
a
a
a
a
aa
aa
aa
aaa
aaa
If single-character palindromes do not count, then we have 6.
Either way, you need to consider all substrings as possible palindromes; not only the ones in the middle. Comparing a string against its reversed self is very easy to do in Python: s == s[::-1].
Getting all the substrings is easy too:
def get_all_substrings(input_string):
length = len(input_string)
return [input_string[i:j+1] for i in range(length) for j in range(i,length)]
and filtering out strings of length < 2 is also easy:
substrings = [a for a in get_all_substrings(string) if len(a) > 1]
Combining these should be fairly straight forward:
len([a for a in get_all_substrings(string) if len(a) > 1 and a == a[::-1]])
I think you should write a function(f) individually to check if a string is a palindrome.
Then make a function(g) that selects sub-strings of letters.
Eg: in string abcd, g will select a, b, c, d, ab, bc, cd, abc, bcd, abcd. Then apply f on each of these strings individually to get the number of palindromes.

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

Checking charcters in a string and outputing a Single message

a_lst = ['chair','gum','food','pizza']
letter = 'x'
for word in a_lst:
if letter not in word:
print ('no',letter)
elif letter in word:
print ('yes',letter)
Output:
no x
no x
no x
no x
Is there a way i can iterate though each item in "a_lst", check if each item has letter 'x'. if no item has letter 'x' print 'no x' just Once. If a word contains letter 'x', print 'yes x' just Once.
I think my logic is flawed somewhere.
Any suggestions?
Thanks
You could do this:
letter = 'x'
result = [a for a in a_lst if letter in a]
if result:
print('yes', letter)
else:
print('no', letter)
Explanation:
result will be [] if none of the words in a_lst has the letter. When you do a if result on an empty list, it returns False, otherwise it returns True. The conditional statements check and print the output statement accordingly.
Another way to do it in python is to use the filter function:
if filter(lambda x: letter in x, a_lst):
print('yes', letter)
else:
print('no', letter)
Yet another way to do it is to use any:
if any(letter in word for word in a_list):
print('yes', letter)
else:
print('no', letter)
any(letter in word for word in a_list) returns True if any of the words have the letter.
You can use the any function!
if any(letter in word for word in a_lst):
print('yes', letter)
else:
print('no', letter)
Have you tried something like this:
a = ['chair', 'gum', 'food', 'pizza']
letter = 'a'
result = 'no ' + letter
k = 0
for i in a:
if letter in a[k]:
print(a[k])
result = 'yes ' + letter
k += 1
print(result)