Force case on dictionary to compare user input in Python - python

I'm making a user input decision tree and I want to force the dictionary that the input is being compared to into lowercase. I've placed .lower() at various points and keep getting errors.
not_found = True
while True:
if OPTIONS == "1" or 'a':
ARTIST_PICK = str(raw_input(
"Please pick an artist\n"
"Or Q to quit: ")).lower
print ARTIST_PICK
**entries = allData(filename).data_to_dict()
for d in entries:
arts = d['artist']**
if ARTIST_PICK in arts:
print "found it"
elif ARTIST_PICK == 'q':
break
else:
print "Sorry, that artist could not be found. Choose again."
not_found = False
This is a sample of the "entries" I'm trying to make lower and compare the user input to:
[{'album': 'Nikki Nack', 'song': 'Find a New Way', 'datetime': '2014-12-03 09:08:00', 'artist': 'tUnE-yArDs'},]

If your problem was just comparing the artist names, then you could use list comprehension to make everything lowercase.
entries = allData(filename).data_to_dict()
if ARTIST_PICK in [ d['artist'].lower() for d in entries ]:
print("found it")
elif ARTIST_PICK == "q":
break
else
print("Sorry, that artist could not be found. Choose again.")
Or if you'd rather use a for loop (rearranged a little for readability):
if(ARTIST_PICK != 'q'):
entries = allData(filename).data_to_dict()
found = False
for d in entries:
if ARTIST_PICK == d['artist'].lower():
found = True
break
elif ARTIST_PICK == "q":
break
if(found):
print("found it")
else:
print("Sorry, that artist could not be found. Choose again.")
else:
# handle the case where the input is 'q' here if you want
By the way, as a matter of principle you should name your boolean variables as though you were using them in a sentence. Instead of setting a variable not_found to False if the variable isn't found, set a variable named found to False or set not_found to True. Makes things easier in the long run.

ARTIST_PICK = str(raw_input(
"Please pick an artist\n"
"Or Q to quit: ")).lower()

Related

Pythom programming how can I exclude the values for if statement from the dictionary list with loop

How can I write orders with loop, dictionary and if statement by python
If I want the output result from dictionary list and for the others input print a sentence
Here is my program could someone find what is the solution for the mistakes
def phone_guide():
guide_number = input("Enter a number:")
numbers = {"Amal": 1111111111, "Mohammed": 2222222222, "Khadijah": 3333333333, "Abdullah": 4444444444}
While guide_number == 1111111111:
print("Amal")
elif guide_number == 2222222222:
print("Mohammed")
elif guide_number == 3333333333:
print("khadijah")
elif guide_number == 4444444444:
print("Abdullah")
elif guide_number != numbers:
print("Sorry, the number is not found")
#This mean the number has to be from the dictionary list
else:
print("This is invalid number")
#This mean if the number less or more than 10 number or different value or string
phone_guide()
There are multiple issues you need to fix. The indentation is wrong and the loop has issues. You need to iterate over the dictionary and check if value exists.
def phone_guide():
print "Enter a number:"
guide_number = input()
numbers = {"Amal": 1111111111, "Mohammed": 2222222222, "Khadijah": 3333333333, "Abdullah": 4444444444}
for key,value in numbers.items():
if guide_number == value:
print(key)
return
print("Sorry, the number is not found")
phone_guide()
First of all, its unneccessarily complicated to store name: number if you want to check the number. Is it possible to reverse it like number: name?
numbers = {1111111111: "Amal", 2222222222: "Mohammed", ...}
Secondary you don't need all these if/elif/else statements. You can check if an item is in a dictionaries keys or values.
1111111111 in numbers.keys() or 1111111111 in numbers.values()
To match your phone numbers validity you can use a regex like this and check if typeof(phone_number) == int.
import re
invalid = 1234568
valid = 0123456789
re.match(r'\d+{10}', valid)
>>> True
re.match(r'\d+{10}', invalid)
>>> False
Given all these information you should be able to come to the solution.
There are multiple errors in your code. Go through the basics of python again.
def phone_guide():
guide_number = int(input("Enter a number:"))
numbers = {"Amal": 1111111111, "Mohammed": 2222222222, "Khadijah": 3333333333, "Abdullah": 4444444444}
for key, value in numbers.items():
if guide_number == value:
return key
return "This is invalid number"
def phone_guide():
guide_number = input("Enter a number:")
numbers = {"Amal": 1111111111, "Mohammed": 2222222222, "Khadijah": 3333333333, "Abdullah": 4444444444}
if guide_number == 1111111111:
print("Amal")
elif guide_number == 2222222222:
print("Mohammed")
elif guide_number == 3333333333:
print("khadijah")
elif guide_number == 4444444444:
print("Abdullah")
elif guide_number != numbers:
print("Sorry, the number is not found")
else:
print("This is invalid number")
Write your code as above. In python you can only use elif after if.

Editing a list of dictionaries from a list created from a txt file

I am trying to exclude and remove some dictionaries from a list. I have searched for awhile through the site and haven't found anything specific to this. The list of dictionaries was created from a txt file located: http://s000.tinyupload.com/?file_id=48953557772434487729
I'm trying to sort out and exclude the things I don't need. I thought my syntax was right, but apparently not.
I only included necessary code to cut down on the clutter. I am having problems at the action_genre point and excluding and deleting the dictionaries there. When prompted enter "s" and then "a" to access those two menus.
def load_movies():
global movies_list
movies_list= []
file_ref = open("movies.txt", 'r')
line = file_ref.readline()
for line in file_ref:
line = line.strip()
current = {}
if line == '':
break
movie_data = line.split("\t")
current["title"] = movie_data[0]
current["year"] = movie_data[1]
current["length"] = movie_data[2]
current["rating"] = movie_data[3]
current["action"] = int(movie_data[4][0]) == 1
current["animation"] = int(movie_data[4][1]) == 1
current["comedy"] = int(movie_data[4][2]) == 1
current["drama"] = int(movie_data[4][3]) == 1
current["documentary"] = int(movie_data[4][4]) == 1
current["romance"] = int(movie_data[4][5]) == 1
movies_list.append(current)
del current
file_ref.close()
def menu():
movie_selector =("Movie Selector - Please enter an option below:\nL - List all movies\nY - List all movies by year\n"
"T - Search by title\nS - Search by genre, rating, and maximum length\nQ - Quit the program\nOption:")
movie_selector_input = input(movie_selector).upper()
if movie_selector_input == "L":
list_movies()
if movie_selector_input == "Y":
list_by_year()
if movie_selector_input == "T":
search_by_title()
if movie_selector_input == "S":
search()
if movie_selector_input == "Q":
print("Thanks for using my program! Goodbye.")
exit()
else:
print("Invalid input")
print("Please try again")
print()
return menu()
def search():
genre_input = input("Please make a selection from the following genres.\n(Action(A), Animation(N), Comedy(C), "
"Drama(D), Documentary(O), or Romance(R)):").lower()
if genre_input == 'a':
action_genre()
elif genre_input == 'n':
animation_genre()
elif genre_input == 'c':
comedy_genre()
elif genre_input == 'd:':
drama_genre()
elif genre_input == 'o':
documentary_genre()
elif genre_input == 'r':
romance_genre()
else:
print("Invalid genre")
print()
menu()
#this is where I can't get the syntax to work
def action_genre():
for current in movies_list:
if current["action"] == "False":
del current
break
for i in movies_list:#using this to test output
print(i)
load_movies()
menu()
I'm narrowing down the list by excluding things that don't fit the parameters. In the action_genre function, I'm trying to delete all the dictionaries that don't equal current["action"] == True. I've tried using "True" and "False" as strings, as well as the bools True and False for comparisons, and still an error. Unfortunately, I have to use the Boolean logic per my professors directions.
His e.g.:
Professor's example. Apparently since I'm new I can't embed images. :/
I'm in programming 101, so thank you for your patience as I learn this, and thank you in advance for the help.
Okay, so the issue runs a bit deeper than the if condition being incorrect. In get_action() you effictively do not modify the actual movies_list object, but rather the local variable current, as proven by this simple test:
def action_genre():
for current in movies_list:
print(current)
if not current["action"]:
del current
print(current)
The second print(current) will result in an UnboundLocalError saying that current does not exist anymore, while in movies_list the entry it just deleted continues to exist. But in general, using del in loops indeed causes problems because that's how iterables and del itself behave. I encourage you to read up more on this on other sources or SO if you wish, like here.
Using the answer from the provided link above, we can use list comprehension to filter the movies:
def action_genre():
filtered_movies_list = [movie for movie in movies_list if movie['action']]
print(filtered_movies_list)
This creates a new list (so it does not modify movies_list), which includes all dictionary entries where item['action'] == True.
I hope this helps.
You are trying to compare a string with a boolean. Look at the following:
a= 1==1
print a
True
print type(a)
<class 'bool'> # a is a boolean
b='True' #assign string 'True' to b
print type(b)
<class 'str'>
print a==b #compare boolean True to string 'True'
False
b = True # assign boolean True to b
print a==b #compare boolean True to boolean True
True
so you need if current["action"] == False instead of if current["action"] == "False"

Python Invalid Else Placement (Beginner)

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.

Python - class Flashcard - quizzing user in a loop

I am trying to create a loop that quizzes the user with flashcards I have created. When the user wants to exit, they should be able to type the letter 'q' and have the number of correct and incorrect answers print. Here is what I have:
class Flashcard(object):
def __init__(self, q, a) :
self.question = q
self.answer = a
def print_question(self) :
print self.question
def quiz_user(self) :
self.print_question()
ans = raw_input("? ")
correct = 0
incorrect = 0
if ans.strip().lower() == self.answer.strip().lower() and ans.strip().lower() != 'q':
print "Good job!"
correct = correct + 1
return True
elif ans.strip().lower() != self.answer.strip().lower() and ans.strip().lower() != 'q':
print "Sorry, the answer was:", self.answer
incorrect = incorrect + 1
return False
elif ans.strip().lower() == 'q':
print "correct:", correct
print "incorrect:", incorrect
import random
cards = [
Flashcard("What is largest country in Africa?", "Algeria"),
Flashcard("What is a group of larks called?", "exaltation")
]
while True :
random.choice(cards).quiz_user()
When I run the code, I get an error saying that the "local variable 'incorrect' referenced before assignment". How can I keep track of the correct and incorrect answers? Should I be returning more than just True and False in quiz_user()? Would it help to make the quiz loop in a new class?
Yeah you need to declare the two variables first, and then pass them in to and get them out each time, so try this:
correct = 0
incorrect = 0
cards = [
Flashcard("What is largest country in Africa?", "Algeria"),
Flashcard("What is a group of larks called?", "exaltation")
]
while True :
result = random.choice(cards).quiz_user()
if result: correct += 1
elif not result: incorrect += 1
else: break
That should allow you to keep using your True False structure, and have the code work. You could also then get rid of your references to correct and incorrect inside your class, and put the print statements in the while loop. Also change this:
elif ans.strip().lower() == 'q':
print "correct:", correct
print "incorrect:", incorrect
to this:
elif ans.strip().lower() == 'q': return None
to have the program stop when q is entered.

How to make the user only enter one character at a time

OK so what I need to do is make my code only allow the user to enter one letter and then one symbol at a time. The example below shows what I want in a better view.
At the moment my code allows the user to enter more than one character at a time which I don't want.
What letter would you like to add? hello
What symbol would you like to pair with hello
The pairing has been added
['A#', 'M*', 'N', 'HELLOhello']
What I want is a message to be displayed like this and the pairing not to be added to the list.
What letter would you like to add? hello
What symbol would you like to pair with hello
You have entered more than one character, the pairing was not added
['A#', 'M*', 'N',].
So far my code for this section is as follows...
It would also be great for when the user enters a number in the letter section, an error message to be printed.
def add_pairing(clues):
addClue = False
letter=input("What letter would you like to add? ").upper()
symbol=input("\nWhat symbol would you like to pair with ")
userInput= letter + symbol
if userInput in clues:
print("The letter either doesn't exist or has already been entered ")
elif len(userInput) ==1:
print("You can only enter one character")
else:
newClue = letter + symbol
addClue = True
if addClue == True:
clues.append(newClue)
print("The pairing has been added")
print (clues)
return clues
The easiest way to ensure user input is with a loop:
while True:
something = raw_input(prompt)
if condition: break
Something set up like this will continue to ask prompt until condition is met. You can make condition anything you want to test for, so for you, it would be len(something) != 1
Your method can be simplified to the following if you let the user enter a letter and symbol pair:
def add_pairing(clues):
pairing = input("Please enter your letter and symbol pairs, separated by a space: ")
clues = pairing.upper().split()
print('Your pairings are: {}'.format(clues))
return clues
Not exactly sure what you want to return but this will check all the entries:
def add_pairing(clues):
addClue = False
while True:
inp = input("Enter a letter followed by a symbol, separated by a space? ").upper().split()
if len(inp) != 2: # make sure we only have two entries
print ("Incorrect amount of characters")
continue
if not inp[0].isalpha() or len(inp[0]) > 1: # must be a letter and have a length of 1
print ("Invalid letter input")
continue
if inp[1].isalpha() or inp[1].isdigit(): # must be anything except a digit of a letter
print ("Invalid character input")
continue
userInput = inp[0] + inp[1] # all good add letter to symbol
if userInput in clues:
print("The letter either doesn't exist or has already been entered ")
else:
newClue = userInput
addClue = True
if addClue:
clues.append(newClue)
print("The pairing has been added")
print (clues)
return clues
I am fan of raising and catching exceptions in similar cases. Might be shocking for people with 'C-ish' background (sloooow), but it is perfectly pythonic and quite readable and flexibile in my opinion.
Also, you should add check for characters outside of set you are expecting:
import string
def read_paring():
letters = string.ascii_uppercase
symbols = '*##$%^&*' # whatever you want to allow
letter = input("What letter would you like to add? ").upper()
if (len(letter) != 1) or (letter not in letters):
raise ValueError("Only a single letter is allowed")
msg = "What symbol would you like to pair with '{}'? ".format(letter)
symbol = input(msg).upper()
if (len(symbol) != 1) or (symbol not in symbols):
raise ValueError("Only one of '{}' is allowed".format(symbols))
return (letter, symbol)
def add_pairing(clues):
while True:
try:
letter, symbol = read_paring()
new_clue = letter + symbol
if new_clue in clues:
raise ValueError("This pairing already exists")
break # everything is ok
except ValueError as err:
print(err.message)
print("Try again:")
continue
# do whatever you want with letter and symbol
clues.append(new_clue)
print(new_clue)
return clues

Categories

Resources