i am trying to create a program which is a computer diagnostic service. I want to be able to ask the user what their problem is then extract key words from it. Then I want to print a solution. For example, the user says "My screen is broken", the program recognises "screen" and prints the solution for a broken screen. I honestly have no idea how to do this and i really need some help. Thanks!
with some dictionary of keywords to solutions d,
d = {'screen': 'Get a new screen', ...}
problem = input('What did you do? ').lower()
for k in d:
if k in problem:
print(d[k])
For each keyword, check if it's in the problem. If it is, print the associated solution
This works too
import re
D = {'screen': 1, 'keyboard': 2, 'mouse': 3}
keywords = set(D)
wordre = re.compile(r'\w+')
problem = "The cursor doesn't move on the screen when I move the mouse"
found = set(wordre.findall(problem.lower())) & keywords
print(found) # prints {'mouse', 'screen'}
Your question doesn't specify if your code will impose any limitations with regards to the extent of the user's input.
Assuming that the user will be able to describe his problem to a great extent (i.e input raw text as opposed to just typing a sentence or two) you can use the summa module.
If you take a look at its documentation, you will see that by applying its keywords function on any text; you can extract keywords out of it. Consequently, you can parse those arguments to print the respective solutions. A simple way to do this is to maintain a dictionary with your keywords of interest as keys and their solutions as values; and then just simply cross-check the summa generated keywords against these to print your final solution.
Related
I recently just asked a question on SO regarding on how to turn a text file into a dictionary on Python, it worked until I made a slight adjustment to the code as I want to compare the key to a word in a string, and if the key was the same as the word, it would print the corresponding value, however no output is printed, why is this?
def answerInput():
print("Hello, how may I help you with your mobile device")
a = input("Please enter your query below\n")
return a
def solution(answer):
string = answer
my_dict = {}
with open("Dictionary.txt") as f:
for line in f:
key, value = line.strip("\n").split(maxsplit=1)
my_dict[key] = value
for word in string.split():
if word == my_dict[key]:
print(value)
process = 0
answer = answerInput()
solution(answer)
If anyone it helps, my text file is as goes:
battery Have you tried charging your phone? You may need to replace your battery.
dead Have you tried charging your phone? You may need to replace your battery.
sound Your volume may be on 0 or your speakers may be broken, try using earphones.
screen Your screen may be dead, you may need a replacement.
touchID You may need to wipe the fingerprint scanner, try again.
microphone You may need to replace your microphone.
Read the file into my_dict dictionary first, then do lookups into it (your current code as posted reads the file as it does the lookups). Also, compare the words of the user's answer to the keys, not values of the my_dict dictionary (as your code does).
All of this also means that the code should have 3 parts, perhaps something similar to the solution below.
def read_dictionary(in_file):
my_dict = {}
with open(in_file) as f:
for line in f:
key, value = line.strip('\n').split(maxsplit=1)
my_dict[key] = value
return my_dict
def read_query():
print('Hello, how may I help you with your mobile device')
return input('Please enter your query below\n').strip('\n')
def solve(query, my_dict):
for word in query.split():
if word in my_dict:
print(my_dict[word])
return
return
my_dict = read_dictionary('Dictionary.txt')
query = read_query()
solve(query, my_dict)
you're trying to compare the variable 'answer' to the variable 'key', not the value stored in my_dict[key].
also, I'd suggest you use .lower() such as: if answer.lower() == key
so you'd be able to process user responses even if they are in upper case letters
I'm not sure if this is the way you want it to work and configparser usage is a little different but I kinda like the way it can work here.
import configparser
config = configparser.ConfigParser()
config.read("conf.ini", encoding="utf-8")
def answerInput():
print("Hello, how may I help you with your mobile device")
a = input("Please enter your query below\n")
return a
answer = answerInput()
print(config.get("Answers", answer))
conf.ini file in the same directory:
[Answers]
battery = Have you tried charging your phone? You may need to replace your battery.
dead = Have you tried charging your phone? You may need to replace your battery.
sound = Your volume may be on 0 or your speakers may be broken, try using earphones.
screen = Your screen may be dead, you may need a replacement.
touchID = You may need to wipe the fingerprint scanner, try again.
microphone = You may need to replace your microphone.
This is obviously depending if you already have a huge list of those key value pairs or you are gonna be creating ones. If you are creating ones, this might be a nice strucured way to do it.
I have a code that allows me to identify keywords inputted from a user and the system displays the problem the keyword linked to and asks if it is correct. If the user inputs yes a solution is given
# The following is a database of problems, keywords, and solutions.
PROBLEMS = (('My phone does not turn on.',
{'power', 'turn', 'on', 'off'},
('put it on charger.',))
# These are possible answers accepted for yes/no style questions.
POSITIVE = tuple(map(str.casefold, ('yes', 'true', 'correct')))
NEGATIVE = tuple(map(str.casefold, ('no', 'false', 'incorrect')))
def main():
"""Find out what problem is being experienced and provide a solution."""
description = input('Welcome to the repair centre. Please state the problem with your device: ')
words = {''.join(filter(str.isalpha, word))
for word in description.lower().split()}
for problem, keywords, steps in PROBLEMS:
if words & keywords:
print('This may be what you are experiencing:')
print(problem)
if get_response('Does this match your problem? '):
print('Please follow the solution given')
for number, step in enumerate(steps, 1):
print('{}. {}'.format(number, step))
print('Once you have carried out the solution suggested by the system the problem with your device should be fixed .')
print('If you have carried out the solution suggested by the system and the problem is not fixed, please take the device to either the manufacturer or to the repair shop to get it fixed professionally.')
break
else:
print('Unfortunately the repair centre cannot help you with your problem.')
def get_response(query):
"""Ask the user yes/no style questions and return the results."""
while True:
answer = input(query).casefold()
if answer:
if any(option.startswith(answer) for option in POSITIVE):
return True
if any(option.startswith(answer) for option in NEGATIVE):
return False
print('Please respond with the positive or negative answer listed : yes, true, correct, no, false, incorrect.')
if __name__ == '__main__':
main()
However how can i store all the solutions in a text file and make the keywords stored in python link to it depending on the user input.
I want a specific line from the text file to be outputted to the user.
Help will be appreciated
We're going to store the keywords and solutions in a csv file. The first entry on each line will be the solution, and all the others will be keywords that direct to this solution.
from collections import defaultdict
import csv
sol_dict = defaultdict(set)
with open('solutions.csv', newline='') as f:
r = csv.reader(f, quotechar='|')
for solution, *keywords in r:
for keyword in keywords:
sol_dict['keyword'].add(solution)
So now we have this dictionary, sol_dict. We can query a keyword sol_dict['power'] and you get back a set of strings, each a solution. (When you make the csv, if you want commas in the solution, you can wrap it in the quotechar, |).
Then walking through the solutions would look something like
problem = input('What is your problem?')
for solution in set.union(*(sol_dict[word] for word in problem.split())):
# Whatever you want to do with solutions
print(solution)
As part of my project, I want to ask the user to enter an order from existing orders in a list.
So this is the problem: If my user writes the order in the input not exactly as its written in the list, how will my program understand it?
In other words, I want to turn this into Python code:
if (part of) string in order_list:
How can I do this?
order = input()
orders_list = ["initiate", "eat", "run", "set coords to"]
#Here is the problem
if order in orders_list:
#my output
For example, lets say I entered "eating" instead of "eat". How will my code
understand that I meant "eat"?
You can see if any of your words are contained in the users word like this:
if any(word in order for word in orders_list):
#my output
>>> from difflib import get_close_matches
>>> orders_list = ["initiate", "eat", "run", "set coords to"]
>>> get_close_matches('eating', orders_list)
['eat']
The fact that you are struggling with this should be an indication that your data structure is wrong.
Instead of getting the user to write a single string, get them to enter individual elements and store them separately in a list.
I'm trying to write something that will ask users to input a specific domain (say, Google.com), and if _spf.google.com is in the SPF TXT record for Google.com, I want it to say "Yup". If not, I want it to say "Nope." Right now, the code will ask me for the domain, and it'll look up the SPF record, but I can't get it to say "yup." Why not? I've tried turning it into a string, but even that wouldn't get me what I wanted. What am I doing wrong here?
To add to that, what would you guys recommend is a good jumping off point for figuring out what code I'd need to write to figure out how many DNS lookups an SPF record is ultimately using?
import dns.resolver
question= raw_input("What domain do you want? ")
def PrintandGoogle(question):
answer=dns.resolver.query(question,"TXT")
for data in answer:
print data
if "_spf.google.com" in answer:
print "Yup."
else:
print "Nope."
printAndGoogle(question)
If your if is inside your loop:
if "_spf.google.com" in data.to_text():
If your if is outside your loop:
if any("_spf.google.com" in data.to_text() for data in answer):
I am working on script that needs to be able to track revisions. The general idea is to give it a list of tuples where the first entry is the name of a field (ie "title" or "description" etc.), the second entry is the first version of that field, and the third entry is the revised version. So something like this:
[("Title", "The first version of the title", "The second version of the title")]
Now, using python docx I want my script to create a word file that will show the original version, and the new version with the changes bolded. Example:
Original Title:
This is the first version of the title
Revised Title:
This is the second version of the title
The way that this is done in python docx is to create a list of tuples, where the first entry is the text, and the second one is the formatting. So the way to create the revised title would be this:
paratext = [("This is the ", ''),("second",'b'),(" version of the title",'')]
Having recent discovered difflib I figured this would be a pretty easy task. And indeed, for simple word replacements such as sample above, it is, and can be done with the following function:
def revFinder(str1,str2):
s = difflib.SequenceMatcher(None, str1, str2)
matches = s.get_matching_blocks()[:-1]
paratext = []
for i in range(len(matches)):
print "------"
print str1[matches[i][0]:matches[i][0]+matches[i][2]]
print str2[matches[i][1]:matches[i][1]+matches[i][2]]
paratext.append((str2[matches[i][1]:matches[i][1]+matches[i][2]],''))
if i != len(matches)-1:
print ""
print str1[matches[i][0]+matches[i][2]:matches[i+1][0]]
print str2[matches[i][1]+matches[i][2]:matches[i+1][1]]
if len(str2[matches[i][1]+matches[i][2]:matches[i+1][1]]) > len(str1[matches[i][0]+matches[i][2]:matches[i+1][0]]):
paratext.append((str2[matches[i][1]+matches[i][2]:matches[i+1][1]],'bu'))
else:
paratext.append((str1[matches[i][0]+matches[i][2]:matches[i+1][0]],'bu'))
return paratext
The problems come when I want to do anything else. For example, changing 'teh' to 'the' produces t h e h (without the spaces, I couldn't figure out the formatting). Another issue is that extra text appended to the end is not shown as a change (or at all).
So, my question to all of you is what alternatives are there to difflib which are powerful enough to handle more complicated text comparions, or, how can I use difflib better such that it works for what I want? Thanks in advance