Python - Searching a dictionary for strings - python

Basically, I have a troubleshooting program, which, I want the user to enter their input. Then, I take this input and split the words into separate strings. After that, I want to create a dictionary from the contents of a .CSV file, with the key as recognisable keywords and the second column as solutions. Finally, I want to check if any of the strings from the split users input are in the dictionary key, print the solution.
However, the problem I am facing is that I can do what I have stated above, however, it loops through and if my input was 'My phone is wet', and 'wet' was a recognisable keyword, it would go through and say 'Not recognised', 'Not recognised', 'Not recognised', then finally it would print the solution. It says not recognised so many times because the strings 'My', 'phone' and 'is' are not recognised.
So how do I test if a users split input is in my dictionary without it outputting 'Not recognised' etc..
Sorry if this was unclear, I'm quite confused by the whole matter.
Code:
import csv, easygui as eg
KeywordsCSV = dict(csv.reader(open('Keywords and Solutions.csv')))
Problem = eg.enterbox('Please enter your problem: ', 'Troubleshooting').lower().split()
for Problems, Solutions in (KeywordsCSV.items()):
pass
Note, I have the pass there, because this is the part I need help on.
My CSV file consists of:
problemKeyword | solution
For example;
wet Put the phone in a bowl of rice.

Your code reads like some ugly code golf. Let's clean it up before we look at how to solve the problem
import easygui as eg
import csv
# # KeywordsCSV = dict(csv.reader(open('Keywords and Solutions.csv')))
# why are you nesting THREE function calls? That's awful. Don't do that.
# KeywordsCSV should be named something different, too. `problems` is probably fine.
with open("Keywords and Solutions.csv") as f:
reader = csv.reader(f)
problems = dict(reader)
problem = eg.enterbox('Please enter your problem: ', 'Troubleshooting').lower().split()
# this one's not bad, but I lowercased your `Problem` because capital-case
# words are idiomatically class names. Chaining this many functions together isn't
# ideal, but for this one-shot case it's not awful.
Let's break a second here and notice that I changed something on literally every line of your code. Take time to familiarize yourself with PEP8 when you can! It will drastically improve any code you write in Python.
Anyway, once you've got a problems dict, and a problem that should be a KEY in that dict, you can do:
if problem in problems:
solution = problems[problem]
or even using the default return of dict.get:
solution = problems.get(problem)
# if KeyError: solution is None
If you wanted to loop this, you could do something like:
while True:
problem = eg.enterbox(...) # as above
solution = problems.get(problem)
if solution is None:
# invalid problem, warn the user
else:
# display the solution? Do whatever it is you're doing with it and...
break

Just have a boolean and an if after the loop that only runs if none of the words in the sentence were recognized.

I think you might be able to use something like:
for word in Problem:
if KeywordsCSV.has_key(word):
KeywordsCSV.get(word)
or the list comprehension:
[KeywordsCSV.get(word) for word in Problem if KeywordsCSV.has_key(word)]

Related

how to make a program ignore everything but the key word in users input?

datadict = {}#open the file
with open('phoneproblemquery.txt') as file:
for line in file:
problem, answer = line.split('-')
problems = problem.strip().split(' ')
for item in problems:
datadict[item] = answer
user_problem = input('What is the problem?:')
print(datadict[user_problem])
The text-file contains something like this:
screen - replace screen.
if I were to run this program and enter in 'screen' the program will respond 'replace screen'. but, if I were to enter something like 'the screen'(not just 'screen' alone) the program will give a 'keyError' and won't work.
what would I need to do to if the user enters 'the screen' (instead of just 'screen') for the program to provide an output 'replace screen'. would I need to put the users answer into arrays? if so how?
Thanks!
update: 'the screen' was just an example. The user can enter in any
form of way i.e 'screen is...' the keyword is screen. I would want
the program to identify the key word from the users input and get
the response 'replace screen'. ... ;( desperate for an answer...
You want the program to pick keywords out of the user input and look for them in datadict. The difficulty with that is picking out keywords. A simple approach is to have regular expressions rather than simple keywords as the keys of your lookup dictionary. You will of course have to do the matching yourself: the dictionary lookup process won't do it for you.
import re
datadict = {}
#open the file
with open(r'phoneproblemquery.txt') as file:
for line in file:
problem, answer = line.split('-')
problems = problem.strip().split(' ')
for item in problems:
datadict[re.compile(fr'{item}', re.IGNORECASE)] = answer
user_problem = input('What is the problem?:')
for regex, diagnosis in datadict.items():
if regex.search(user_problem):
print (diagnosis)
This will work, but in a more sophisticated implementation it might be better to put the regular expressions in the input data, rather than constructing them at runtime like I have done here. You are already allowing for something of the sort by having a space-delimited list if keywords in your input data. If you had regular expressions in the input instead, the same would apply, only instead of, say
keyboard kybd - replace keyboard
you would have
keyboard|kybd - replace keyboard
and in that event maybe a hyphen would not be the best delimiter. A carriage return might be better, since that can never appear in the input.

Using One String in a Dictionary For an If-Statement (Python 3)

diction1 = {"Pikachu","Harambe","Potato"}
name = input()
if name == diction1:
print("Yay")
^Except it doesn't work.
High schooler here, studying dictionaries. Just wanna know how do I get an input from one variable to match one of the strings in my dictionary to comply with my if-statement.
Sorry, by the way, if this question has been asked already. I'm not too familiar with the terms, so I may have not been able to search the right questions.
First of all it's not a dictionary but set. It's also based on hash-tree. You should check it in the following way:
if name in diction1:
# do stuff

Use generic keys in dictionary in Python

I am trying to name keys in my dictionary in a generic way because the name will be based on the data I get from a file. I am a new beginner to Python and I am not able to solve it, hope to get answer from u guys.
For example:
from collections import defaultdict
dic = defaultdict(dict)
dic = {}
if cycle = fergurson:
dic[cycle] = {}
if loop = mourinho:
a = 2
dic[cycle][loop] = {a}
Sorry if there is syntax error or any other mistake.
The variable fergurson and mourinho will be changing due to different files that I will import later on.
So I am expecting to see my output when i type :
dic[fergurson][mourinho]
the result will be:
>>>dic[fergurson][mourinho]
['2']
It will be done by using Python
Naming things, as they say, is one of the two hardest problems in Computer Science. That and cache invalidation and off-by-one errors.
Instead of focusing on what to call it now, think of how you're going to use the variable in your code a few lines down.
If you were to read code that was
for filename in directory_list:
print filename
It would be easy to presume that it is printing out a list of filenames
On the other hand, if the same code had different names
for a in b:
print a
it would be a lot less expressive as to what it is doing other than printing out a list of who knows what.
I know that this doesn't help what to call your 'dic' variable, but I hope that it gets you on the right track to find the right one for you.
i have found a way, if it is wrong please correct it
import re
dictionary={}
dsw = "I am a Geography teacher"
abc = "I am a clever student"
search = re.search(r'(?<=Geography )(.\w+)',dsw)
dictionary[search]={}
again = re.search(r'(?<=clever )(.\w+)' abc)
dictionary[search][again]={}
number = 56
dictionary[search][again]={number}
and so when you want to find your specific dictionary after running the program:
dictionary["teacher"]["student"]
you will get
>>>'56'
This is what i mean to

Writing and Editing Files (Python)

First of all i would like to apologize since i am a beginner to Python. Anyway I have a Python Program where I can create text files with the general form:
Recipe Name:
Item
Weight
Number of people recipe serves
And what I'm trying to do is to allow the program to be able to retrieve the recipe and have the ingredients recalculated for a different number of people. The program should output the the recipe name, the new number of people and the revised quantities for the new number of people. I am able to retrieve the recipe and output the recipe however i am not sure how to have the ingredients recaculated for a different number of people. This is part of my code:
def modify_recipe():
Choice_Exist = input("\nOkaym it looks like you want to modify a recipe. Please enter the name of this recipe ")
Exist_Recipe = open(Choice_Exist, "r+")
time.sleep(2)
ServRequire = int(input("Please enter how many servings you would like "))
I would recommend splitting your effort into multiple steps, and working on each step (doing research, trying to write the code, asking specific questions) in succession.
1) Look up python's file I/O. 1.a) Try to recreate the examples you find to make sure you understand what each piece of the code does. 1.b) Write your own script that accomplishes just this piece of your desired program, i.e. opens an exist recipe text file or creates a new one.
2) Really use you're own functions in Python particularly with passing your own arguments. What you're trying to make is a perfect example of good "modular programming", were you would right a function that reads an input file, another that writes an output file, another that prompts users for they number they'd like to multiple, and so on.
3) Add a try/except block for user input. If a user enters a non-numeric value, this will allow you to catch that and prompt the user again for a corrected value. Something like:
while True:
servings = raw_input('Please enter the number of servings desired: ')
try:
svgs = int(servings)
break
except ValueError:
print('Please check to make sure you entered a numeric value, with no'
+' letters or words, and a whole integer (no decimals or fractions).')
Or if you want to allow decimals, you could use float() instead of int().
4) [Semi-Advanced] Basic regular expressions (aka "regex") will be very helpful in building out what you're making. It sounds like your input files will have a strict, predictable format, so regex probably isn't necessary. But if you're looking to accept non-standard recipe input files, regex would be a great tool. While it can be a bit hard or confusing skill to learn, but there are a lot of good tutorials and guides. A few I bookmarked in the past are Python Course, Google Developers, and Dive Into Python. And a fantastic tool I strongly recommend while learning to build your own regular expression patterns is RegExr (or one of many similar, like PythonRegex), which show you what parts of your pattern are working or not working and why.
Here's an outline to help get you started:
def read_recipe_default(filename):
# open the file that contains the default ingredients
def parse_recipe(recipe):
# Use your regex to search for amounts here. Some useful basics include
# '\d' for numbers, and looking for keywords like 'cups', 'tbsp', etc.
def get_multiplier():
# prompt user for their multiplier here
def main():
# Call these methods as needed here. This will be the first part
# of your program that runs.
filename = ...
file_contents = read_recipe_file(filename)
# ...
# This last piece is what tells Python to start with the main() function above.
if __name__ == '__main__':
main()
Starting out can be tough, but it's very worth it in the end! Good luck!
I had to edit it a couple times because I use Python 2.7.5, but this should work:
import time
def modify_recipe():
Choice_Exist = input("\nOkay it looks like you want to modify a recipe. Please enter the name of this recipe: ")
with open(Choice_Exist + ".txt", "r+") as f:
content = f.readlines()
data_list = [word.replace("\n","") for word in content]
time.sleep(2)
ServRequire = int(input("Please enter how many servings you would like: "))
print data_list[0]
print data_list[1]
print int(data_list[2])*ServRequire #provided the Weight is in line 3 of txt file
print ServRequire
modify_recipe()

Python program to search for specific strings in hash values (coding help)

Trying to write a code that searches hash values for specific string's (input by user) and returns the hash if searchquery is present in that line.
Doing this to kind of just learn python a bit more, but it could be a real world application used by an HR department to search a .csv resume database for specific words in each resume.
I'd like this program to look through a .csv file that has three entries per line (id#;applicant name;resume text)
I set it up so that it creates a hash, then created a string for the resume text hash entry, and am trying to use the .find() function to return the entire hash for each instance.
What i'd like is if the word "gpa" is used as a search query and it is found in s['resumetext'] for three applicants(rows in .csv file), it prints the id, name, and resume for every row that has it.(All three applicants)
As it is right now, my program prints the first row in the .csv file(print resume['id'], resume['name'], resume['resumetext']) no matter what the searchquery is, whether it's in the resumetext or not.
lastly, are there better ways to doing this, by searching word documents, pdf's and .txt files in a folder for specific words using python (i've just started reading about the re module and am wondering if this may be the route, rather than putting everything in a .csv file.)
def find_details(id2find):
resumes_f=open("resume_data.csv")
for each_line in resumes_f:
s={}
(s['id'], s['name'], s['resumetext']) = each_line.split(";")
resumetext = str(s['resumetext'])
if resumetext.find(id2find):
return(s)
else:
print "No data matches your search query. Please try again"
searchquery = raw_input("please enter your search term")
resume = find_details(searchquery)
if resume:
print resume['id'], resume['name'], resume['resumetext']
The line
resumetext = str(s['resumetext'])
is redundant, because s['resumetext'] is already a string (since it comes as one of the results from a .split call). So, you can merge this line and the next into
if id2find in s['resumetext']: ...
Your following else is misaligned -- with it placed like that, you'll print the message over and over again. You want to place it after the for loop (and the else isn't needed, though it would work), so I'd suggest:
for each_line in resumes_f:
s = dict(zip('id name resumetext'.split(), each_line.split(";"))
if id2find in s['resumetext']:
return(s)
print "No data matches your search query. Please try again"
I've also shown an alternative way to build dict s, although yours is fine too.
What #Justin Peel said. Also to be more pythonic I would say change
if resumetext.find(id2find) != -1: to if id2find in resumetext:
A few more changes: you might want to lower case the comparison and user input so it matches GPA, gpa, Gpa, etc. You can do this by doing searchquery = raw_input("please enter your search term").lower() and resumetext = s['resumetext'].lower(). You'll note I removed the explicit cast around s['resumetext'] as it's not needed.
One change that I recommend for your code is changing
if resumetext.find(id2find):
to
if resumetext.find(id2find) != -1:
because find() returns -1 if id2find wasn't in resumetext. Otherwise, it returns the index where id2find is first found in resumetext, which could be 0. As #Personman commented, this would give you the false positive because -1 is interpreted as True in Python.
I think that problem has something to do with the fact that find_details() only returns the first entry for which the search string is found in resumetext. It might be good to make find_details() into a generator instead and then you could iterate over it and print the found records out one by one.

Categories