How do you check for multiple specific words in a string? - python-2.7

I am working on a text-based game, and want the program to search for multiple specific words in order in the user's answer. For example, I wan't to find the words "Take" and "item" in a user's response without making the user type specifically "Take item".
I know that you can use
if this in that
to check if this word is in that string, but what about multiple words with fluff in between?
The code I am using now is
if ("word1" and "word2" and "word3) in ans:
but this is lengthy and won't work for every single input in a text-based game. What else works?

A regex based solution might be to use re.match:
input = "word1 and word2 and word3"
match = re.match(r'(?=.*\bword1\b)(?=.*\bword2\b)(?=.*\bword3\b).*', input)
if match:
print("MATCH")
The regex pattern used makes use of positive lookaheds which assert that each word appears in the string.

We might here want to design a library with keys and values, then look up for our desired outputs, if I understand the problem correctly:
word_action_library={
'Word1':'Take item for WORD1',
'Some other words we wish before Word1':'Do not take item for WORD1',
'Before that some WOrd1 and then some other words':'Take items or do not take item, if you wish for WORD1',
'Word2':'Take item for WORD2',
'Some other words we wish before Word2':'Do not take item for WORD2',
'Before that some WOrd2 and then some other words':'Take items or do not take item, if you wish for WORD2',
}
print list(value for key,value in word_action_library.iteritems() if 'word1' in key.lower())
print list(value for key,value in word_action_library.iteritems() if 'word2' in key.lower())
Output
['Take items or do not take item, if you wish for WORD1', 'Do not take item for WORD1', 'Take item for WORD1']
['Take items or do not take item, if you wish for WORD2', 'Do not take item for WORD2', 'Take item for WORD2']

Related

How to I shorten this code to comply with the DRY (Don't Repeat Yourself) principle?

I want to take words a user provides, store them in a list, and then modify those words so that every other letter is capitalized. I have working code but it is repetitive. I cannot for the life of me figure out how to get all the words ran through in one function and not have it output one long string with the spaces removed. Any help is appreciated.
This is my current code:
def sarcastic_caps(lis1):
list=[]
index=0
for ltr in lis1[0]:
if index % 2 == 0:
list.append(ltr.upper())
else:
list.append(ltr.lower())
index=index+1
return ''.join(list)
final_list.append(sarcastic_caps(lis1))
Imagine 4 more iterations of this ^. I would like to do it all in one function if possible?
I have tried expanding the list index but that returns all of the letters smashed together, not individual words. That is because of the .join but I need that to get all of the letters back together after running them through the .upper/.lower.
I am trying to go from ['hat', 'cat', 'fat'] to ['HaT', 'CaT', 'FaT'].

'list' object has no attribute 'replace' while trying to input "and" in a list

Write a program that prints a list with all the items separated by a comma and a space, with 'and' inserted before the last item. The above list would print 'apples, bananas, tofu, and cats'. But the program should be able to work with any list not just the one shown above. Because of this, I'll need to use a loop in case the list to print is shorter or longer than the above list. The program should work for all user inputs without "and" or commas if the list only contains one item.

compare list items against another list

So lets say I have 3 item list:
myString = "prop zebra cool"
items = myString.split(" ")
#items = ["prop", "zebra", "cool"]
And another list content containing hudreds of string items. Its actally a list of files.
Now I want to get only the items of content that contain all of the items
So I started this way:
assets = []
for c in content:
for item in items:
if item in c:
assets.append(c)
And then somehow isolate only the items that are duplicated in assets list
And this would work fine. But I dont like that, its not elegant. And Im sure that there is some other way to deal with that in python
If I interpret your question correctly, you can use all.
In your case, assuming:
content = [
"z:/prop/zebra/rig/cool_v001.ma",
"sjasdjaskkk",
"thisIsNoGood",
"shakalaka",
"z:/prop/zebra/rig/cool_v999.ma"
]
string = "prop zebra cool"
You can do the following:
assets = []
matchlist = string.split(' ')
for c in content:
if all(s in c for s in matchlist):
assets.append(c)
print assets
Alternative Method
If you want to have more control (ie. you want to make sure that you only match strings where your words appear in the specified order), then you could go with regular expressions:
import re
# convert content to a single, tab-separated, string
contentstring = '\t'.join(content)
# generate a regex string to match
matchlist = [r'(?:{0})[^\t]+'.format(s) for s in string.split(' ')]
matchstring = r'([^\t]+{0})'.format(''.join(matchlist))
assets = re.findall(matchstring, contentstring)
print assets
Assuming \t does not appear in the strings of content, you can use it as a separator and join the list into a single string (obviously, you can pick any other separator that better suits you).
Then you can build your regex so that it matches any substring containing your words and any other character, except \t.
In this case, matchstring results in:
([^\t]+(?:prop)[^\t]+(?:zebra)[^\t]+(?:cool)[^\t]+)
where:
(?:word) means that word is matched but not returned
[^\t]+ means that all characters but \t will match
the outer () will return whole strings matching your rule (in this case z:/prop/zebra/rig/cool_v001.ma and z:/prop/zebra/rig/cool_v999.ma)

How do you create a translator in Python?

What I am trying to do is make a program react with words I define to translate it into a language, or in my case, letters.
This would be an example of what I want:
I type in "Woof" per say. I want it to be able to understand what I say when I type woof, and print a letter with it.
So let's say "Woof" is the letter "A"
And let's say "Arf bark" is the letter "B"
I've had no luck finding how to be able to input say "Woof arf bark" and get it to print "AB"
My end goal is to be able to translate words with my own little translator using my own defined language by simply inputing words.
What I'm looking for in a response is simply an example of inputing a defined word and receiving a letter or something in response.
Long story-short; I am basically looking for a translator
Edit: Imagine Google Translate, you type in a word or a series of letters or whatever be the case, and it becomes translated.
I'm looking for it to be able to UNDERSTAND INPUT. So If I copy and paste the made up language, the IDE should be able to give me a translation of it.
Better Example: Let's say H is defined as "8" because it is the 8th letter in the alphabet, and A is defined as "1" due to being the first letter in the alphabet.
How do I write a program that allows me to input "8181" and have it translated to say "Haha"
Semicolons and Duct Tap's answer provides a neat way to do this, provided that you can filter the input however you want to.
Using only his suggestion, however, you would not be able to parse "Woof arf bark": This would get split into ["Woof","arf","bark"]. You would, however, be able to parse "Woof, arf bark".
That might be enough for you. If not, read on...
Handling complicated input
If you want to separate things using a character that might be in one of your words, as in your example (woof arf bark) things get a bit more complicated.
Based on that example, it might be worth looking into regular expressions.
These can give you a better way to parse input, if you want to be able to recognize everywhere in your string that matches a word you need to output.
This will let you make things look simple to the user, but can also slow things down if you have a long string and a complicated expression to match. If you choose this path, you could use re.findall() to separate your text.
An example
Using a dictionary, lets say you have:
words = {"woof":A,"arf bark":B}
input = "woof,arf bark"
inputList = input.split(',')
for word in inputList:
print words[word]
This example does not use a regular expression (or regex)
A = raw_input("Enter a word to be transcribed to A")
#user types "Woof"
check = raw_input("Enter your secret code")
if check == A:
print "A"
#will print out "A"
You are basically asking for a dictionary.
here is how to use them in Python:
http://www.tutorialspoint.com/python/python_dictionary.htm
and a little code that demonstrates their use lifted from the page:
#!/usr/bin/python
dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First', 'your word': 'translated word'};
print "dict['Name']: ", dict['Name']
print "dict['Age']: ", dict['Age']
print "dict['your word']: ", dict['your word'] #dict['your name'] will return 'translated word'
just add all your fake language into dictionary keys and what you want the words translated to in the keys' value locations.
you can then take a string and split it on a delimiter of your choice (you suggest using a comma in your comments) and then send the values you get in the split list to the dictionary to translate the string.
With the translate module:
from translate import Translator
languageName=input('Enter language name:')
transalat=input('What to transalate?:')
translator = Translator(to_lang=languageName)
translation = translator.translate(transalat)
print(translation)

How to loop through array of strings Python

in order to execute this code, which basically deletes a word from a sentence, we have to use split.string in order to access words.
def censor(text, word):
splitstring=text.split()
for elem in range(len(splitstring)):
if splitstring[elem]==word:
splitstring[elem]='*'*len(word)
return " ".join(splitstring)**strong text**
why can't we use use a "traditional" for-loop, as if looping through a word for a letter?
for word in text:
for elem in word:
if elem==word:
word='*'*len(word) """etc"""
There are multiple questions here:
When we iterate over a string of text, why do we get individual letters not words ?
The Zen of Python states "There should be one-- and preferably only one --obvious way to do it."
A string is a just string of characters. It may or may not have individual words in it. The most obvious way to iterate over a string is one character at a time.
When we iterate using "for word in text" and modify "word", why doesn't "text" change ?
The answer has two parts to it:
(a) Strings are immutable in Python, so whenever you modify a string, you get a new string while the original one remains unmodified. So there is no way to modify string "text" other than by reassigning "text" to a new string.
(b) Even if strings were mutable, when you iterate over an iterable, you only get copies of the elements. So modifying them has no effect on the iterable object.
"for elem in range(len(splitstring))" looks clumsy. What is the right way to do this in Python ?
Ok, I made up this question. But the answer is still important. The Pythonic way to do this is:
for elem in splitstring:
Or if you need the index of each element, then you do this:
for index, elem in enumerate(splitstring):