I was wondering if someone could help me see what i am doing wrong with this search function for a binary search tree. Have to use the iterative version due to the size of data. I keep getting stuck in an infinite while loop when i print out values for debugging. Thanks!
I also get this error:
while (word_search.value != user_input) and (word_search.value != None):
AttributeError: 'NoneType' object has no attribute 'value'
def iterative_word_search(current, user_input):
word_search = current.root
print("User input value", user_input)
print("Word Search Value", word_search.value)
while (word_search.value != None) and (word_search.value != user_input):
print("While Loop value: ", word_search.value)
if(user_input < word_search.value):
word_search = word_search.left
# print("If statement value: " ,word_search.value)
elif(word_search.right != None):
word_search = word_search.right
print("Else statement value: ", word_search.value)
elif(word_search.value == None):
print("Word does not exist")
return word_search
return word_search
You need to assert that left and right are not None before calling .value on them:
Python lazy evaluation of expressions allows you to do this on one line. if word_search is None or word_search.value is None will evaluate word_search, and if it is None, will not evaluate word_search.value.
def iterative_word_search(current, user_input):
word_search = current.root
while True:
if word_search is None or word_search.value is None:
print("not found")
break
if word_search.value == user_input:
print("found")
break
if(user_input < word_search.value):
word_search = word_search.left
elif(word_search.right != None):
word_search = word_search.right
return word_search
Thank you for all the help!
Solved the problem. It dealt with user input and the files that i read in.
The files that i read in had a '\N' attached to it. Which is why i kept getting multiple errors and it was not searching the word.
Related
This part of my if statement calls the find_feed function and it it returns None, the if statement completes, however if it returns anything else, the else statement re-calls the function: news_feed = feedparser.parse(find_feed(user_input))
Instead of calling the function twice (because it takes a bit to complete), I'd like to call it once and if it doesn't return None, use the returned value in the else statement instead of calling the function again. Can I do that, and if so, how?
elif find_feed(user_input) is None:
print("No location found.")
else:
print("Pulling weather data from Environment Canada.")
news_feed = feedparser.parse(find_feed(user_input))
brief_current()
more_question = input("\n" + "Would you like more details? (y or n) ")
if more_question == "y":
detailed_current()
Since PEP 572 in Python 3.8 you can also combine if statement with assignment so you don't have to create the variable in advance:
elif (unparsed_news_feed := find_feed(user_input)) is None:
print("No location found.")
else:
print("Pulling weather data from Environment Canada.")
news_feed = feedparser.parse(unparsed_news_feed)
brief_current()
more_question = input("\n" + "Would you like more details? (y or n) ")
if more_question == "y":
detailed_current()
Although here I'd suggest swapping two branches and inverting is None to is not None so unparsed_news_feed is only used in its corresponding branch.
Store the return value in a variable, so you can reference it later. See here:
xy = find_feed(x)
# Assumes a pre existing if statement
elif xy is None:
print('no location')
else:
print("Pulling weather data from Environment Canada.")
news_feed = feedparser.parse(xy)
brief_current()
more_question = input("\n" + "Would you like more details? (y or n) ")
if more_question == "y":
detailed_current()
You need to save the result of the call to find_feed before you test its value:
else: # instead of the original elif find_feed(user_input) is None:
result = find_feed(user_input)
if result is None:
print("No location found.")
else:
print("Pulling weather data from Environment Canada.")
news_feed = feedparser.parse(result)
brief_current()
more_question = input("\n" + "Would you like more details? (y or n) ")
if more_question == "y":
detailed_current()
def SearchEntryComment():
print("\n\nSearch for guestbook comment with a keyword\n")
CommentSearch = input("Enter key word for search: ")
for i in range(len(dlGuestBook)):
if CommentSearch in dlGuestBook[i]["Comment"]:
print(i+1, ".", dlGuestBook[i] ["FirstName"], dlGuestBook[i]["LastName"], dlGuestBook[i]["Date"])
print(dlGuestBook[i]["Comment"], "\n")
else:
print("No results found")
print("\n")
This is my current code however when I run it for every element in the list it will print "no results found" and if it is there it will print that one. I want it to either print the results that are there or just no results found.
just using resultCount to save count of result found in list, and check the count after for loop.
def SearchEntryComment():
print("\n\nSearch for guestbook comment with a keyword\n")
CommentSearch = input("Enter key word for search: ")
resultCount = 0
for i in range(len(dlGuestBook)):
if CommentSearch in dlGuestBook[i]["Comment"]:
print(i+1, ".", dlGuestBook[i] ["FirstName"], dlGuestBook[i]["LastName"], dlGuestBook[i]["Date"])
print(dlGuestBook[i]["Comment"], "\n")
resultCount += 1
if resultCount == 0:
print("No results found")
print("\n")
Look closely at what your for loop is doing.
for i in range(len(dlGuestBook)): # for each entry in the guestbook
if CommentSearch in dlGuestBook[i]["Comment"]:
# print the comment
else:
print("No results found")
I think what you want is to only print "No results found" after your loop finishes, if it hasn't found any results. Something like this might be a solution.
foundComment = False
for i in range(len(dlGuestBook)):
if CommentSearch in dlGuestBook[i]["Comment"]:
foundComment = True
# print the comment
if not foundComment:
print("No results found")
I want to print the other_activity if its not empty after taking input from user but this error, I know its pretty basic but not able to find the solution
print("What kind of activity is this?")
print '\n'.join(acti)
userInput = raw_input("\n""Client->")
r = re.compile(userInput)
if not filter(r.match, acti):
print("not valid activity")
else:
if (userInput == "Other"):
event_activity = raw_input("-> Please specify your activity\n""Client->")
other_activity = ("Other:" + event_activity)
else:
event_activity = userInput
if not other_activity:
print("Activity type: ", other_activity)
else:
print("Activity type: ", event_activity)
Define other_activity = None at the top of your code (There are cases in your code when other_activity is never assigned, and thus, never created. By adding this default assignment, you are making sure the variable will exist when checking its value)
At the end, you can use a ternary condition to print one variable or the other:
print('Activity type:', other_activity if other_activity else event_activity)
I'm getting a syntax error after an else statment. Is it due to indentation?
if choice == 2:
actor = input('Enter actor:')
actorLower = actor.lower()
for name in actors:
nameLower = name.lower()
if actorLower in nameLower:
print(actors[name])
else:
print('Actor not found')
elif choice == 1:
movie = input('Enter movie:')
print(moviedict[movie])
else: #**This is where I'm getting the syntax error**
print('Movie not found')
elif choice != 0:
print('Invalid choice')
query('movies.txt')
In plain english, else means otherwise, so you have to specify a condition of validity (the if key word) and a case when this if is not met (that is your else)
From your example on the second block:
elif choice == 1:
movie = input('Enter movie:')
print(moviedict[movie])
else:
print('Movie not found')
is not valid because
else:
print('Movie not found')
does not have a if, you never test if the movie belongs to the dictionnary. A solution to that would be:
movie = input("Enter movie:")
if movie in moviedict.keys():
print(moviedict[movie])
else:
print('Movie not found')
Would be a solution in that case. Same thing for your first "Actor not found"
The error occurs here
elif choice == 1:
movie = input('Enter movie:')
print(moviedict[movie])
else:
print('Movie not found')
You have added an else statement without an if. That is the reason it says invalid else placement. Either add a if before the else or remove the else part.
So here's my question:
I want to search a dictionary to see if any key contains a user-inputted keyword. For example, the user searches for John.
elif option == 3:
count = 0
found = None
search_key = input("What do you want to search for? ").lower()
for key, val in telephone_directory.items(): #takes each element in telephone directory
if search_key in key: #checks if it contains search_key
if found is None:
found = val
count = 1
if found is not None:
print(" ")
print("More than one match found. Please be more specific.")
print(" ")
count = 2
break
if found is None:
print("Sorry, " + str(search_key) + " was not found.")
print(" ")
function_options() #redirects back
if found is not None and count < 2:
print(str(search_key) + " was found in the directory.")
print("Here is the file on " + str(search_key) + ":")
print(str(search_key) + ":" + " " + telephone_directory[search_key])
print(" ")
function_options() #redirects back
So this is where I am right now. Whatever the search may be, even if it is the entire key, it returns "was not found". What am I doing wrong?
You need to make a few choices; allow multiple matches, find only the first match, or only allow for at most one match.
To find the first match, use next():
match = next(val for key, val in telephone_directory.items() if search_key in key)
This will raise StopIteration if no match was found; return a default instead or catch the exception:
# Default to `None`
match = next((val for key, val in my_dict.items() if search_key in key), None)
try:
match = next(val for key, val in telephone_directory.items() if search_key in key)
except StopIteration:
print("Not found")
These versions will only loop over the dictionary items until a match is found, then stop; the full for loop equivalent would be:
for key, val in telephone_directory.items():
if search_key in key:
print("Found a match! {}".format(val))
break
else:
print("Nothing found")
Note the else block; it is only called when the for loop was allowed to complete, and was not interrupted by a break statement.
To find all matching keys, use can use a list comprehension:
matches = [val for key, val in telephone_directory.items() if search_key in key]
Finally, to allow for only one match, efficiently, use two next() calls on the same iterator, and raise an error if a second match is found:
def find_one_match(d, search_key):
d = iter(d.items())
try:
match = next(val for key, val in d if search_key in key)
except StopIteration:
raise ValueError('Not found')
if next((val for key, val in d if search_key in key), None) is not None:
raise ValueError('More than one match')
return match
Adapting that to the for loop approach again, would require you to break only if a second item is found:
found = None
for key, val in telephone_directory.items():
if search_key in key:
if found is None:
found = val
else:
print("Found more than one match, please be more specific")
break
else:
if found is None:
print("Nothing found, please search again")
else:
print("Match found! {}".format(found))
Your version doesn't work because you print 'not found' for each and every key that doesn't match. You can only know that you didn't match a key until the very end when you've iterated over all the keys in your dictionary.