Comparing and printing elements in nested loops - python

The program identifies if one of the elements in the string word is a consonant by looping though the word string, and then for each iteration though the word string, iterating though the consonants list and comparing if the current element in word string equals to the current element of consonant list.
If yes, the current element of the word string is a consonant and the consonant gets printed (not the index of the consonant, but the actual consonant, for e.g. "d".)
The problem is, I get this instead:
1
1
What am I doing wrong? Shouldn't the nested loops work so that the below loop iterates every element for each element in the above loop? That is, each index above makes the below loop iterate though each index?
That's the program:
word = "Hello"
consonants = ['b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'z']
for character in range(len(word)):
for char in range(len(consonants)):
if consonants[char] == word[character]:
consonant = word[character]
print consonant

You are misreading the output. The character is the letter L lowercase, not the number 1.
In other words, your code is working as designed. The captital letter H is not in your consonants list, but the two lowercase letters l in Hello are.
Note that it'd be much more efficient to use a set for consonants here; you'd not have to loop over that whole list and just use in to test for membership. That works with lists too, but is much more efficient with a set. If you lowercase the word value you'd also be able to match the H.
Last but not least, you can loop over the word string directly rather than use range(len(word)) then use the generated index:
word = "Hello"
consonants = set('bcdfghjklmnpqrstvwxz')
for character in word.lower():
if character in consonants:
print character
Demo:
>>> word = "Hello"
>>> consonants = set('bcdfghjklmnpqrstvwxz')
>>> for character in word.lower():
... if character in consonants:
... print character
...
h
l
l

Related

List modification doesn't change list

I'm trying to reverse a string, so I converted the string into a list and was trying to send the last element to the front, 2nd to last element to the 2nd space, etc.
word = input("Enter a word: ")
word = list(word)
count = 0
while count < len(word):
word.insert(count, word.pop())
count = count + 1
print(word)
It just returns the original string in list form, even though I'm saving the last letter and inserting it before popping it off of the string? Does word.pop() not capture the last letter of a string before deleting it or am I overlooking something?
Well the simplest way to do what you are trying is to slice the string in reverse order, this does not even require changing into a list:
word = input("Enter a word: ")
return word[::-1]
Here's an experiment:
>>> word = list('python')
>>> word.insert(0, word[-1])
>>> word
['n', 'p', 'y', 't', 'h', 'o', 'n']
>>> word.remove(word[-1])
>>> word
['p', 'y', 't', 'h', 'o', 'n']
Wait, what?!
>>> help(word.remove)
Help on built-in function remove:
remove(value, /) method of builtins.list instance
Remove first occurrence of value.
Raises ValueError if the value is not present.
Remove first occurrence of value.
So, you inserted word[-1] at the beginning of the list, and then word.remove immediately removes the first occurrence of word[-1], which is now at the beginning of the list, you've just inserted it there!
You're setting the variables inside the while-loop to the same value. Also, use list.pop to remove the element from the list. For example:
word = input("Enter a word: ")
word = list(word)
count = 0
while count < len(word):
word.insert(count, word.pop())
count = count + 1
print(word)
Prints:
Enter a word: book
['k', 'o', 'o', 'b']
Here is the docstring for list.remove:
>>> help(list.remove)
Help on method_descriptor:
remove(self, value, /)
Remove first occurrence of value.
Raises ValueError if the value is not present.
>>>
As you can see, list.remove removes the first occurrence of the given value from the list. All your backwards function does right now is take the last character of the word, add it to the front and then immediately remove it from the front again. You do this once for every character in the word, the net result being no change.

Converting to lower-case: every letter gets tokenized

I have a text document that I want to convert to lower case, but when I do it in the following way every letter of my document gets tokenized. Why does it happen?
with open('assign_1.txt') as g:
assign_1 = g.read()
assign_new = [word.lower() for word in assign_1]
What I get:
assign_new
['b',
'a',
'n',
'g',
'l',
'a',
'd',
'e',
's',
'h',]
You iterated through the entire input, one character at a time, dropped each to lower-case, and specified the result as a list. It's simpler than that:
assign_lower = g.read().lower()
Using the variable "word" doesn't make you iterate over words -- assign_1 still a sequence of characters.
If you want to break this into words, use the split method ... which is independent of the lower-case operation.

Eliminating last element in array

So I am working on a small hangman text based game.
The problem I am currently dealing with is calling random words from my text file. Each word has one additional character for a new line (\n).
For instance, running through my function that separates a string's letters into individual elements I get something to the effect of:
from text file: guess
answer = arrange_word(guess)
>>>>> ['g', 'u', 'e', 's', 's', '\n']
however, when joining the array back together the following is shown:
print ''.join(arrange_word)
>>>>> guess
as you can see, it is a bit difficult to guess an element that does not show up.
For clarity here is my function for arrange_word:
def arrange_word(word):
##########
# This collects the mystery word and breaks it into an array of
# individual letters.
##########
word_length = len(word)
break_up = ["" for x in range(word_length)]
for i in range(0, word_length):
break_up[i] = word[i]
return break_up
What I am stuck on is that when trying to guess letters, the \n is impossible to guess. The win condition of my game is based on the guess being identical to the answer word. However the \n keeps that from working because they are of different length.
These answer arrays are of different length as well, since I am just pulling random lines from a text file of ~1000 words. After hours of searching I cannot seem to find out how to drop the last element of an array.
For this line here:
word_length = len(word)
Before you take the length, what you can do is this first:
word = word.strip()
Explanation:
strip removes leading and trailing whitespace.
>>> s = "bob\n"
>>> s
'bob\n'
>>> s.strip()
'bob'
With all this in mind, you don't need the rest of this code anymore:
word_length = len(word)
break_up = ["" for x in range(word_length)]
for i in range(0, word_length):
break_up[i] = word[i]
Applying the strip will give you your word without the whitespace character, then all you want to do after this to have a list of characters, is simply:
>>> s = "bob"
>>> list(s)
['b', 'o', 'b']
So your method can now simply be:
def arrange_word(word):
return list(word.strip())
Demo:
arrange_word("guess")
Output:
['g', 'u', 'e', 's', 's']
All these answers are fine for specifically stripping whitespace characters from a string, but more generally, Python lists implement standard stack/queue operations, and you can make your word into a list just by calling the list() constructor without needing to write your own function:
In [38]: letters = list('guess\n')
letters.pop()
letters
Out[38]: ['g', 'u', 'e', 's', 's']
Use List slicing
arr = [1,2,3,4]
print(arr[:-1:])
Array slicing syntax is [startindex:endindex:offset(2, means each 2 element)] So in your case you could. Which mean start at the begging of the list, to the last element -1 for every 1 element in the list.
return break_up[:-1:]
you can access last element by -1 index like:
guess[-1]
and you can delte it by:
del guess[-1]
Just strip the word:
word = 'guess\n'
word = word.strip() ## 'guess' without new line character, or spaces
Maybe first line of your arrange_word function should be
word = word.strip()
to remove all leading/trailing whitespace characters.

Python regular expression that will find words made out of specific letters. Letters must be used once only

If I have a list of words in the variable words and a list of letters in the variable letters, how can I find all the words that can be made up out of the letters in letters. The letters in letters must only be used once each; but you can list the same letter more than once. All letters in letters must be used. I would like to do this in Python or Excel VBA.
For example:
letters = ['a', 'a', 'a', 'i', 'l', 'r', 's', 't', 'u']
words = ['dummy', 'australia']
I wouldn't use a regex for this, especially in Python:
>>> [w for w in words if sorted(w) == letters]
['australia']
This assumes that letters is sorted, as in your example.

How to find if a secret word contains all the characters from a list?

I have been trying to solve this problem because it is a part of constructing Hangman game.
My problem is that I need to write a code which would check if all the list items are in the secret word. If all are in a list, it will return True, if not, False.
This is my work I have done:
def isWordGuessed(secretWord, lettersGuessed):
a_list = []
for i in range(0, len(lettersGuessed)):
a_list.append(lettersGuessed[i])
str1 = ''.join(a_list)
if str1 in secretWord:
return 1
else:
return 0
isWordGuessed('apple', ['e', 'i', 'k', 'p', 'r', 's'])
However, I have tried to do this:
isWordGuessed('apple', ['a', 'p', 'l', 'p', 'e'])
It returns False, even though all letters in a list are in 'apple'
I guess I could solve this without making a string but I don't how. By the way, this must work for any word and list given. If all list items are in a word, it is true, otherwise false...Any help?
I would convert the secret word and the already guessed letters both to sets and check whether the set of the characters of the secret word is a subset of the set of the guessed characters:
def isWordGuessed(secretWord, lettersGuessed):
return set(secretWord) <= set(lettersGuessed)

Categories

Resources