Searching for 2 word key in dictionary - python

im new in python and world of programming. get to the point. when i run this code and put input let say chicken, it will reply as two leg animal. but i cant get reply for two words things that has space in between like space monkey(althought it appear in my dictionary) so how do i solve it???
my dictionary: example.py
dictionary2 = {
"chicken":"chicken two leg animal",
"fish":"fish is animal that live under water",
"cow":"cow is big vegetarian animal",
"space monkey":"monkey live in space",
my code: test.py
from example import *
print "how can i help you?"
print
user_input = raw_input()
print
print "You asked: " + user_input + "."
response = "I will get back to you. "
input_ls = user_input.split(" ")
processor = {
"dictionary2":False,
"dictionary_lookup":[]
}
for w in input_ls:
if w in dictionary2:
processor["dictionary2"] = True
processor["dictionary_lookup"].append(w)
if processor["dictionary2"] is True:
dictionary_lookup = processor["dictionary_lookup"][0]
translation = dictionary2[dictionary_lookup]
response = "what you were looking for is: " + translation
print
print "Response: " + response

You need to explain your purpose to get better help.
In your case you seem to be only interested in looking up words and then this code should be sufficient. Notice the .format() syntax which cleans up your code drastically.
updated code : now a list is created with the combinations found in the input. This however might need modification to fit needs.
dictionary2 = {
"chicken":"chicken two leg animal",
"fish":"fish is animal that live under water",
"cow":"cow is big vegetarian animal",
"space monkey":"monkey live in space"}
print("how can i help you?")
user_input = raw_input()
print("You asked: {}.".format(user_input))
split = user_input.split(" ")
combos = [' '.join(split[x:y]) for x in range(len(split)) for y in range(len(split)+1) if ' '.join(split[x:y]) != ""]
# Create an empty dictionary to insert found item
response = {}
for item in combos:
if dictionary2.get(item):
response[item] = "what you were looking for is: {}.".format(dictionary2[item])
# If dictionary is empty do this
if not response:
print("Response: I will get back to you!")
# If not, loop over keys(k) and values(v) and print them with an index(ind)
for ind, (k,v) in enumerate(response.iteritems()):
print("Response {}: {} ({})".format(ind+1, v, k))

I've redone my answer even though an answer is chosen as this was an interesting problem and I was close to a fair solution in given time.
This answers can take human like questions instead of just words.
Although, for true machine learning nltk is a better option. For start we can use something like below.
It used builtin library difflib to match question against dictionary keys and decided which has higher probability.
Warning: Exception handling is not implemented. It will just pick up max probable match.
We then use re to remove words in key from answer and put everything back together. This provides a more natural answer than just displaying key values.
import re
from difflib import SequenceMatcher
def similarity(a, b):
return SequenceMatcher(None, a, b).ratio()
dictionary2 = {
"chicken":"chicken two leg animal",
"fish":"fish is animal that live under water",
"cow":"cow is big vegetarian animal",
"space monkey":"monkey live in space",}
user_input = raw_input("User Question:")
#Check which key has greater probability match
similarity_list = []
for i in dictionary2.keys():
similarity_list.append((i,similarity(user_input,i)))
key_match = max(similarity_list, key=lambda x:x[1])
uin = ('|'.join(key_match[0].split()))
p = re.compile(r"\b(" + uin + ")\\W", re.I)
ans = p.sub('', dictionary2[key_match[0]])
print "answer: {} {}".format(key_match[0], ans)
Result
Python 2.7.9 (default, Dec 10 2014, 12:24:55) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> ================================ RESTART ================================
>>>
User Question:what is a chicken?
answer: chicken two leg animal
>>> ================================ RESTART ================================
>>>
User Question:Where does space monkey live?
answer: space monkey live in space
>>> ================================ RESTART ================================
>>>
User Question:Where does fish live?
answer: fish is animal that live under water
>>> ================================ RESTART ================================
>>>
User Question:what is a cow?
answer: cow is big vegetarian animal
>>>

The problem with your code is when you use for w in input_ls and what you passed was "space monkey", it looks for space, then it looks for monkey. If you want the desired results with this specific script, it'd look like this
print "how can i help you?"
print
user_input = raw_input()
print
print "You asked: " + user_input + "."
response = "I will get back to you. "
input_ls = user_input
processor = {
"dictionary2":False,
"dictionary_lookup":[]
}
if input_ls in dictionary2:
processor["dictionary2"] = True
processor["dictionary_lookup"].append(input_ls)
if processor["dictionary2"] is True:
dictionary_lookup = processor["dictionary_lookup"][0]
translation = dictionary2[dictionary_lookup]
response = "what you were looking for is: " + translation
print
print "Response: " + response
note I also changed input_ls = user_input.split(" ") to input_ls = user_input because that turns your string into an array of individual words, which wouldn't return what you're looking for if you're trying to look up specific phrases instead of individual words, and made this important change here
if input_ls in dictionary2:
processor["dictionary2"] = True
processor["dictionary_lookup"].append(input_ls)
--edit--
I had to clock out for work, but now that I'm home I can address this better. When trying to accomplish this goal using a dictionary, here's how I would've done it.
dictionary2 = {
"red":"the color red",
"blue":"fish is animal that live under water",
"red and blue":"these colors make blue",
"blue and yellow":"these colors make green"
}
user_input = raw_input('what would you like?\t')
user_input = user_input.split(' ')
print
for word in user_input:
for key,val in dictionary2.iteritems():
if word in key:
print '%s: %s' % (key,val)
When trying to iterate through a dictionary, you need to use either:
dictionary2.iteritems() for both key and val
dictionary2.iterkeys() for your keys
dictionary2.itervalues() for your values

Related

TKinter and JSON

I'm looking for a resource to learning me how to connect TKinter and JSON
Like take an input value (word) and search for that word in JSON then print out the result of the search
by way, I have already the python application working through terminal but I want to go further step and build a GUI
Thank you,
import json #import the JSON module
from difflib import get_close_matches #difflib module provides classes and functions
#for comparing sequences
#get_close_matches Return a list of
#the best “good enough” matches
data = json.load(open("data.json")) #load JSON to python dictionary
def translate(w):
w = w.lower() #change the input to lower case
if w in data: #first scenario check if the word exist in the dictionary, if exist load the data
return data[w]
elif w.title() in data: #When the user inputs a proper noun
return data[w.title()] #returns the definition of names that start with a capital letter
elif w.upper() in data: #definition of acronyms
return data[w.upper()]
elif len(get_close_matches(w, data.keys())) > 0: #second scenario compare the word and get the best match
#ask the user if the result of matching what is looking for
YN = input("Did you mean %s instead? Enter y if yes or n if no:" % get_close_matches(w, data.keys())[0])
if YN == "y":
return data[get_close_matches(w, data.keys())[0]]
elif YN == "n":
return "The word doesn't exist. Please double check it."
else:
return "We didn't understand your entry."
#third scenario the word not match or can't found
else:
return "The word doesn't exsit. Please double check it."
word = input("Enter word: ")
#in some cases the word have more than one definition so we need to make the output more readable
output = translate(word)
if type(output) == list:
for item in output:
print(item)
else:
print(output)
Here's how to do it!
Sketch some pictures of what your current program would look like if it had a GUI.
Would "Did you mean %s instead?" be a popup box?
Would you have a list of all the known words?
Build the UI using tkinter.
Connect the UI up to the functions in your program. (You do have those, don't you?)
Your program isn't quite ready yet, since you are doing stuff like using input inside your functions. Rework it so that it makes sense to have these outside your functions, then it'll probably be ready.

Counting the words a character said in a movie script

I already managed to uncover the spoken words with some help.
Now I'm looking for to get the text spoken by a chosen person.
So I can type in MIA and get every single words she is saying in the movie
Like this:
name = input("Enter name:")
wordsspoken(script, name)
name1 = input("Enter another name:")
wordsspoken(script, name1)
So I'm able to count the words afterwards.
This is how the movie script looks like
An awkward beat. They pass a wooden SALOON -- where a WESTERN
is being shot. Extras in COWBOY costumes drink coffee on the
steps.
Revision 25.
MIA (CONT'D)
I love this stuff. Makes coming to work
easier.
SEBASTIAN
I know what you mean. I get breakfast
five miles out of the way just to sit
outside a jazz club.
MIA
Oh yeah?
SEBASTIAN
It was called Van Beek. The swing bands
played there. Count Basie. Chick Webb.
(then,)
It's a samba-tapas place now.
MIA
A what?
SEBASTIAN
Samba-tapas. It's... Exactly. The joke's on
history.
I would ask the user for all the names in the script first. Then ask which name they want the words for. I would search the text word by word till I found the name wanted and copy the following words into a variable until I hit a name that matches someone else in the script. Now people could say the name of another character, but if you assume titles for people speaking are either all caps, or on a single line, the text should be rather easy to filter.
for word in script:
if word == speaker and word.isupper(): # you may want to check that this is on its own line as well.
recording = True
elif word in character_names and word.isupper(): # you may want to check that this is on its own line as well.
recording = False
if recording:
spoken_text += word + " "
I will outline how you could generate a dict which can give you the number of words spoken for all speakers and one which approximates your existing implementation.
General Use
If we define a word to be any chunk of characters in a string split along ' ' (space)...
import re
speaker = '' # current speaker
words = 0 # number of words on line
word_count = {} # dict of speakers and the number of words they speak
for line in script.split('\n'):
if re.match('^[ ]{19}[^ ]{1,}.*', line): # name of speaker
speaker = line.split(' (')[0][19:]
if re.match('^[ ]{6}[^ ]{1,}.*', line): # dialogue line
words = len(line.split())
if speaker in word_count:
word_count[speaker] += words
else:
word_count[speaker] = words
Generates a dict with the format {'JOHN DOE':55} if John Doe says 55 words.
Example output:
>>> word_count['MIA']
13
Your Implementation
Here is a version of the above procedure that approximates your implementation.
import re
def wordsspoken(script,name):
word_count = 0
for line in script.split('\n'):
if re.match('^[ ]{19}[^ ]{1,}.*', line): # name of speaker
speaker = line.split(' (')[0][19:]
if re.match('^[ ]{6}[^ ]{1,}.*', line): # dialogue line
if speaker == name:
word_count += len(line.split())
print(word_count)
def main():
name = input("Enter name:")
wordsspoken(script, name)
name1 = input("Enter another name:")
wordsspoken(script, name1)
If you want to compute your tally with only one pass over the script (which I imagine could be pretty long), you could just track which character is speaking; set things up like a little state machine:
import re
from collections import Counter, defaultdict
words_spoken = defaultdict(Counter)
currently_speaking = 'Narrator'
for line in SCRIPT.split('\n'):
name = line.replace('(CONT\'D)', '').strip()
if re.match('^[A-Z]+$', name):
currently_speaking = name
else:
words_spoken[currently_speaking].update(line.split())
You could use a more sophisticated regex to detect when the speaker changes, but this should do the trick.
demo
There are some good ideas above. The following should work just fine in Python 2.x and 3.x:
import codecs
from collections import defaultdict
speaker_words = defaultdict(str)
with codecs.open('script.txt', 'r', 'utf8') as f:
speaker = ''
for line in f.read().split('\n'):
# skip empty lines
if not line.split():
continue
# speakers have their names in all uppercase
first_word = line.split()[0]
if (len(first_word) > 1) and all([char.isupper() for char in first_word]):
# remove the (CONT'D) from a speaker string
speaker = line.split('(')[0].strip()
# check if this is a dialogue line
elif len(line) - len(line.lstrip()) == 6:
speaker_words[speaker] += line.strip() + ' '
# get a Python-version-agnostic input
try:
prompt = raw_input
except:
prompt = input
speaker = prompt('Enter name: ').strip().upper()
print(speaker_words[speaker])
Example Output:
Enter name: sebastian
I know what you mean. I get breakfast five miles out of the way just to sit outside a jazz club. It was called Van Beek. The swing bands played there. Count Basie. Chick Webb. It's a samba-tapas place now. Samba-tapas. It's... Exactly. The joke's on history.

Avoid printing identical output

I am making a troubleshooting program, which will ask the user for an input, search through some lists to find the problem and give them a solution.
f=open('problem.txt')
lines=f.readlines()
problem1 = ["cracked", "phone", "screen", "dropped"]
problem2 = ["charging", "port", "phone"]
problem3 = ["slow", "phone", "freeze"]
problem_input = input ("What is your problem? ")
list_split = (problem_input.split( ))
for i in problem1:
if i in list_split:
print (lines[0])
for i in problem2:
if i in list_split:
print (lines[1])
But if i input, "my phone is cracked", the output will be printed twice. How do I only print this once?
You're cycling through a list of problem cases and your input matches twice. The matches are "phone" and "cracked". To prevent that, stop at the first match like that:
for i in problem1:
if i in list_split:
print (lines[0])
break
The break keyword will quit the cycle.
You are looping through your "problems" lists and getting multiple matches for your condition.
You could return your matched problem by making this into a function:
f=open('problem.txt')
lines=f.readlines()
problem1 = ["cracked", "screen", "dropped"]
problem2 = ["charging", "port"]
problem3 = ["slow", "freeze"]
problems = [problem1, problem2, problem3]
def troubleshoot():
problem_input = input("What is your problem? ")
list_split = (problem_input.split())
for idx, problem in enumerate(problems, 1):
if any(i in problem for i in list_split):
return "problem{}".format(idx)
# or return lines[0]
It would run as the following:
>>> troubleshoot()
What is your problem? my phone is slow and freezing up
'problem3'
>>> troubleshoot()
What is your problem? my phone is not charging
'problem2'
>>>
>>> troubleshoot()
What is your problem? my phone dropped and the screen is cracked
'problem1'
Alternatively, if there isn't a reason for having "phone" in each of the problem lists, you might be better off using a dict here:
problems = {'cracked':1, 'screen':1, 'dropped':1,
'charging':2, 'port':2,
'slow':3, 'freeze':3}
user_problems = {problems[i] for i in problem_input.split()}
Note: I removed "phone" from both of these because it matches for every list

Python Dictionary from External file

I am trying to make a dictionary in Python, but I do not know how to do two things.
When I search for keywords in a dictionary, instead of just looking for direct matches, I would like it to find every word that has the keywords in it. E.G. Search: Cat - Results: Cat, Allocate.
I would like the dictionary to load an external file, so new terms that I add to the dictionary can be saved when I load it up afterwards.
You can use following methods:
For 1.
print ("Welcome back to the dictionary");
dict = {"CAT": "A small four legged animal that likes to eat mice",
"DOG": "A small four legged animal that likes to chase cats",
"ALLOCATE": "to give something to someone as ​their ​share of a ​total ​amount, to use in a ​particular way",
}
def Dictionary():
x = input("\n\nEnter a word: \n>>>");
x = x.upper();
found = False
for y in dict:
if x in y:
found = True
print (x,":",dict[x])
Dictionary()
break
if not found:
y = input ("Unable to find word. Enter a new definition of your word: \n>>>");
dict.update({x:y})
Dictionary()
Dictionary()
For 2: You can load data directly from a json file
import json
dict = {}
with open("test.json", "r") as config_file:
dict = json.load(config_file)
where test.json being your file for e.g.
test.json
{"CAT": "A small four legged animal that likes to eat mice",
"DOG": "A small four legged animal that likes to chase cats",
"ALLOCATE": "to give something to someone as ​their ​share of a ​total ​amount, to use in a ​particular way",
}
This should let you match cat in allocate.
for key in dict.keys():
if x in key:
do some stuff

My append command won't work (Python)

I am a new programmer and I am teaching myself using Sams Teach Yourself Python in 24 Hours, and one of the excersises told me to rewrite a piece of code that allows the clerk to work out orders at a restraunt and it told me change it so to include the price, so I did, but I want to use the user's input of the price and to put it into a list to sum it up and print out the total. However, it doesn't work. What should I do?
Here is the code:
breakfast_special = "Texas Omelet"
breakfast_notes = "Contains brisket, horseradish cheddar"
lunch_special = "Greek patty melt"
lunch_notes = "Like the regular onem but with tzatziki sauce"
dinner_special = "Buffalo Steak"
dinner_notes = "Top loin with hot sauce and blue cheese, NOT BUFFALO MEAT"
while True:
meal_time = raw_input("Which mealtime do you want? [breakfast, lunch, dinner, q to quit]")
if meal_time == "q":
break
price = raw_input("Price: $")
price.append(price)
total_price = sum.price
if meal_time == "breakfast":
print "Specials for {} :".format(meal_time)
print breakfast_special
print breakfast_notes
elif meal_time == "lunch":
print "Specials for {} :".format(meal_time)
print lunch_special
print lunch_notes
elif meal_time == "dinner":
print "Specials for {} :".format(meal_time)
print dinner_special
print dinner_notes
else:
print "Sorry, but {} isn't a valid choice".format(meal_time)
print "Goodbye!"
print "Price: ${}".format(total_price)
raw_input() takes a string input.
So when you try to do price = raw_input() , the user input is saved as string type to your variable 'price'. To convert that value to int/float, you can do int(price) or float(price)
Note: You have to make sure the user_input is actually a number. If the variable 'price' has characters, converting it to int/float will result in a ValueError
To achieve what you're trying to do, let's do the following.
first: allocate a new list to hold all the prices you are taking as input. lets call it price_list.
price_list = []
now let's take floating point input form the user for price and append it to the price_list
price = float(raw_input('Price for the item :'))
price_list.append(price)
now that we have a list of prices, lets get the sum of all the prices.
sum(price_list)
That should give you the total sum.
Hope it helps!

Categories