compare user input to list of key words - python

I want to take user input and compare it to a list of key words through a function, if any of the words input by the user match a key word, the condition is met and breaks the loop. If none of the words match a key word, then the console asks for input again. I have been manipulating this loop and have either gotten it to continuously ask for input no matter if a key word is met or validate every word input. Any advice on how to correct it would be great appreciated.
def validated_response(user_complaint):
valid_list = user_complaint.split()
while True:
if user_complaint == "stop":
break
for valid in valid_list:
if valid.lower() not in user_complaint.lower():
print("Response not recognized, please try again")
input("Enter response: ")
continue
else:
print("response validated: ")
break
return True

This function will continue getting user input until the input matches "kwrd1", "kwrd2", or "kwrd3":
def get_input():
keywords = ['kwrd1', 'kwrd2', 'kwrd3']
user_input = None
while True:
user_input = input()
if user_input in keywords:
break
return user_input
If you are matching it against a python keyword, there is a builtin keyword module:
import keyword
def get_input():
user_input = None
while True:
user_input = input()
if keyword.iskeyword(user_input):
break
return user_input

You are always reaching the else statement if the first element in valid_list is not a substring of the user_complaint string. That means you're always breaking out of the for loop and reentering the infinite while loop. Try this instead:
def validated_response(user_complaint):
valid_list = user_complaint.split()
if user_complaint == "stop":
return
inp = input("Enter response: ")
while inp.lower() not in valid_list:
inp = input("Enter response: ")

The provided code has a number of problems. The example does also not show how the function would be called, but I assumed you'd want to call it with a text that has all the keywords you're looking for.
The first problem is you are calling input, but not storing its return value, so you're not actually collecting the user input.
Secondly, you're comparing the various parts of valid_list to the contents of user_complaint.lower(), but that means you're compare a string to the characters in another string - not what you want.
Thirdly, you're asking for new input in a single clause of a condition, inside your loop, so this will lead to messages printing repeatedly and the user having to enter new text before all the comparisons are done.
Finally, you're mixing continue, break and return in a way that doesn't work. continue tells Python to move on to the next cycle of a loop, skipping any remaining code in the current cycle. break tells Python to get out of the current block (in this case the loop). return tells Python to exit the function altogether and return a provided value (or None if none is provided).
Here is an example that more or less follows the structure you set up, but with all of the problems remedied:
def validated_response(keywords):
valid_list = keywords.split()
while True:
user_input = input('Enter response: ').lower().split()
if user_input == ['stop']:
return False
for valid in valid_list:
if valid.lower() in user_input:
print('response validated: ')
return True
print('Response not recognized, please try again')
print(validated_response('trigger test'))

Related

I need advice with while loop in python

I'm using python3 on mac.
I'm currently doing a project. However, I was trying to use "while = True" to continuously use the program until a condition is met. Please, tell me what am I missing in my code. Thanks!
import json
import difflib
from difflib import get_close_matches
data = json.load(open("project1/data.json"))
word = input("Enter a word or enter 'END' to quit: ")
def keyword(word):
word = word.lower()
while type(word) == str:
if word in data:
return data[word]
elif word == 'END'.lower():
break
elif len(get_close_matches(word, data.keys())) > 0:
correction = input("Did you mean %s insted? Enter Yes of No: " % get_close_matches(word, data.keys())[0])
if correction == "Yes".lower():
return data[get_close_matches(word, data.keys())[0]]
elif correction == "No".lower():
return "This word doesn't exist. Plese enter again. "
else:
return "Please enter 'Yes' or 'No: "
else:
return "This word doesn't exist. Please enter again."
print("Thanks!")
output = (keyword(word))
if type(output) == list:
for item in output:
print(item)
else:
print(output)
I think this might be the setup you are looking for.
def keyword(word):
if word in data:
return data[word]
elif len(get_close_matches(word, data.keys())):
correction = input(f"Did you mean {get_close_matches(word, data.keys())[0]} instead? y/n: ")
if correction == 'y':
return data[get_close_matches(word, data.keys())[0]]
elif correction == 'n':
return "This word doesn't exist. Please enter again."
else:
return "Please type 'y' or 'n': "
else:
return "This word doesn't exist. Please enter again."
while True:
word = input("Enter a word: ").lower()
if word == 'end':
print("Thanks!")
break
else:
print(keyword(word))
Looking at the source code and your question, it seems like what you want to achieve is basically to continuously accept input from the user until the user enters something like 'end'. One way to go about this is to separate out the while-loop logic from the function. The overarching while-loop logic is at the bottom half of the code, where we continuously accept input from the user until the user inputs some lower or upper case variant of 'end'. If this condition is not met, we proceed to printing out the result of the function call keyword(word).
Minimal modifications were made to the original keyword() function, but here are a few changes worthy of note:
The while type(word) == str is unnecessary, since the result stored from the input() function will always be a string. In other words, the condition will always return True.
Having return statements within a while loop defeats the purpose of a loop, since the loop will only be executed once. After returning the specified value, the function will exit out of the loop. This is why we need to separate out the loop logic from the function.
Although %s works, it's a relic of C. This might be a matter of personal choice, but I find f-strings to be much more pythonic.
You are using the worng condition.
type((3,4))== list
is False. You must use
type((3,4)) == tuple

Input not returning from function?

I'm making a basic text-based hangman game, and I'm stumped as to why inpLetter is returning None from letterVerify()? It's expected to return a string response so I'm unsure why it isn't.
def letterVerify(prompt):
try:
inp = input(prompt)
verify = str.count(inp)
if (verify > 1) or (verify < 1):
print("Please enter one character.")
if inp not in alphabet or alphabetCaps:
print("Please enter a letter from the English alphabet.")
else:
return inp
except:
print("Please enter a letter from the English alphabet.")
inpLetter = letterVerify("Enter a letter you think is in this word. ")
The problem is in line 4, verify = str.count(inp). count() function returns the number of times a particular character has appeared in a string. It is used as
string = 'abcabcabcabcabc'
string.count('a')
This returns 5. Your code could not find this error because of the try-except block. Whenever this error was raised, it was caught by the exception block, and hence made it difficult to debug. You can rather try using the len() function. This will do the same work you want. It will check if the length of input is 1 or not. Modifications to your code are as
def letterVerify(prompt):
inp = input(prompt)
verify = len(inp)
if verify > 1 or verify < 1:
print('Please enter 1 character')
elif not inp.isalpha():
print('Please enter a letter from English alphabet')
else:
return inp
inpLetter = letterVerify('Enter a letter you think is in this word')
Also, you did not specify what alphabet and alphabetCaps are. I have used isalpha() method, that checks only for alphabetical characters (what you needed). Hope this resolves your issue.
I made your function a little terse for better readability.
First, you should avoid naming your function in camelCase, this violates PEP8. Rather you should use snake_case while naming functions and variables.
Also, simple length checking will do the verify trick. str.count returns the number of times a letter appears in a string, you don't want that here.
You don't need the exception handler here. Python will internally make your inputs str type.
You can lower your string and make comparison with the built in string.ascii_lowercase property. This will eliminate redundant control flow logic.
Here is the function, refactored:
def letter_verify(prompt):
inp = input(prompt)
# remove extra whitespace
inp = inp.strip()
# simple length checking with len function will do the trick
if len(inp) != 1:
print("Please enter one character.")
# just make your input to lowercase and then compare
# this will help you avoid comparison with two cases
elif inp.lower() not in string.ascii_lowercase:
print("Please enter a letter from the English alphabet.")
else:
return inp

What am I doing wrong here? (Python 3) (Beginner)

I'm new to python and I'm trying to create a program that lets the user send words to the program and it will add them to a list then make the list a string and print it.
class joinString():
op_list = [] # this is what i was told to do to initialize a list
def init(self): # idk what this is used for to be honest
print("Hello")
def main(self):
string_in = "" # string input
print("Enter strings, to stop enter a '0'")
while string_in != '0': #while loop checks if string equals '0', stop
string_in = input("String: ") #asks user for inputs
joinString().op_list.append(string_in)
final_string = ''.join(joinString().op_list) # makes final string
print("Final Product: " + final_string) # prints final string
if __name__ == "__main__": #idk what a name is
test = joinString()
test.main()
# I took AP computer science A (coding in java) and scored pretty well but I
# didn't know where to go from there so I'm trying to learn java.
In your main you're using joinString() when you should be using self. A larger issue is that you're writing Java style code in Python. Here's a more Pythonic solution to your problem:
print('Type a word then hit enter. Leave blank to exit.')
words = []
while True:
word = input('Word: ')
if not word:
break
words.append(word)
print(*words)
First we print out a message telling the user how to use the program. We use the empty string to indicate that the users wants to exit.
print('Type a word then hit enter. Leave blank to exit.')
Then we create an empty list, words, to store the user's input.
words = []
Next, we enter an infinity loop (don't worry we'll break out of it later).
while True:
We ask the user to enter a word and store it in word.
word = input('Word: ')
In Python, the empty string is false. So we check if the user entered nothing.
if not word:
If they enter nothing, we break out of the infinite loop.
break
If they entered something, we add the word they entered to the end of words and loop back around.
words.append(word)
Be default, print() puts a space between each object it prints. So, we use the * operate to pass each element of words as an argument to print(). This causes each word to be printed with a space between them.
print(*words)
Hope that helps you learn Python.
Your main method should refer to the instance with self rather than instantiating another instance of joinString with joinString().
Replace:
joinString().op_list.append(string_in)
with:
self.op_list.append(string_in)
and replace:
final_string = ''.join(joinString().op_list)
with:
final_string = ''.join(self.op_list)
Also, the init method should be spelled __init__, and is used to initialize the object when it's being instantiated.
class joinString():
op_list = []
def main(self):
string_in = "" # string input
print("Enter strings, to stop enter a '0'")
while True:
string_in = input("String: ") #asks user for inputs
if string_in == '0':
break
joinString().op_list.append(string_in)
final_string = ''.join(joinString().op_list) # makes final string
print("Final Product: " + final_string) # prints final string
if __name__ == "__main__":
test = joinString()
test.main()
This code is working on my end. I changed your while condition because it was adding 0 to the final string

How to check for valid sequence input?

import re
def check_input():
while True:
try:
sequence = raw_input("Please input:")
if sequence = [a,t,c,g]: # checking for valid input
continue
else:
print("invalid input, sequence coule only contain the "
"following letters (a,t,c,g)"):
check_input()
I basically want the script to check the user's input whether it contains only these four letters (a,t,c,g). If their input contains anything other than that four letters, it could print that second statement and prompt the user to input again. I saw there are similar questions and I already tried to change my script according to those posts but it still gives me the invalid syntax error at the if < sequence position. Anyone knows what's wrong here?
You need to iterate over every letter in the input and check if it is in the set of allowed letters, like this:
sequence = raw_input("Please input:")
for letter in sequence:
if letter not in "atcg":
print("invalid input, sequence coule only contain the following letters (a,t,c,g)")
When you discover that the sequence is invalid, you could choose to end the check by using a break statement after the print, or you could count how many invalid letters are allowed.
Your function must check and give user whether True or False:
def check_input(word):
result = True
for letter in sequene:
if letter in 'atcg':
continue
else:
result = False
break
return result
check_input('atgc')
Error Message:
if check_input('agct'):
continue
else:
print "error message"
You could also use the filter command:
def checkInp():
seq = raw_input("Please input sequence:")
if not filter(lambda m: m not in 'ATGC', seq) == '':
print 'Invalid input characters in sequence: ' + filter(lambda m: m not in 'ATGC', seq)
print 'Pleas'
check_input()
else: return seq
sequence, once input by the user will be a string, so you would need to iterate over each character in the sequence and use in to verify the existence of the character in the accepted characters string. String comparisons in Python are also case sensitive, so you need to match the case of the input to your expected string. I've used uppercase based on your sample input.
def check_input():
sequence = input("Please input:")
sequence.upper()
for letter in sequence:
if letter in 'ATCG':
continue
else:
print("invalid input, sequence could only contain the
following letters: a, t, c or g.")

Returning a list in a function. Also, issue with while loop

I'm having trouble creating a function in Python. I'd like my function to allow a user to input words in a list and ask the user if they'd like to input additional words. If the user inputs 'n', I'd like the function to return the words entered in the list. When I run the function, it asks the user if they'd like to enter an additional word twice. Also, it doesn't return the list.
def add_list(x):
first_list = raw_input('Please input a word to add to a list ')
x.append(first_list)
response = None
while response != 'n':
response = raw_input('Would you like to enter another word? ')
if response == 'n':
print 'Here is the list of words'
return x
else:
add_list(x)
def main():
add_list(x)
x = []
main()
As mentioned above, the reason your code does not return anything is because you don't actually print your results. Furthermore, the reason it continues to ask you if you'd like to enter another word even after you've already said 'n' is due to recursion (i.e. the fact you are calling the function over and over in a nested manner (think nested IFs in Excel, if that helps :) ). Once you get a grasp of the basics you can read up on it more, but for now I would avoid it :)
Here is a basic version of something that will do what you want, with comments that will hopefully help you understand what is going on:
def add_list():
# Since you are starting with an empty list and immediately appending
# the response, you can actually cut out the middle man and create
# the list with the result of the response all at once (notice how
# it is wrapped in brackets - this just says 'make a list from the
# result of raw_input'
x = [raw_input('Please input a word to add to a list: ')]
# This is a slightly more idiomatic way of looping in this case. We
# are basically saying 'Keep this going until we break out of it in
# subsequent code (you can also say while 1 - same thing).
while True:
response = raw_input('Would you like to enter another word? ')
# Here we lowercase the response and take the first letter - if
# it is 'n', we return the value of our list; if not, we continue
if response.lower()[0] == 'n':
return x
else:
# This is the same concept as above - since we know that we
# want to continue, we append the result of raw_input to x.
# This will then continue the while loop, and we will be asked
# if we want to enter another word.
x.append(raw_input('Please input a word to add to the list: '))
def main():
# Here we return the result of the function and save it to my_list
my_list = add_list()
# Now you can do whatever you want with the list
print 'Here is the list of words: ', my_list
main()
I modified your program a little bit:
def add_list(x):
first_list = raw_input('Please input a word to add to a list.')
x.append(first_list)
response = None
while response != 'n':
response = raw_input('Would you like to enter another word? ')
if response.lower() in ['n','no']:
print 'Here is the list of words:', x
return x
else:
x.append(response)
def main():
returned_list = add_list(x)
print "I can also print my returned list: ", returned_list
x = []
main()
First: There is no need for recursion. Instead simply append response to your list x. A nice feature of python is to check if response is not just n, but anything close to n using:
if response.lower() in ['n','no']:
I also edited a line that actually prints the list to your user!
print 'Here is the list of words:', x
Finally, you can also print your list after you return it. Check out the edited def main():.

Categories