How to check if (key belongs to value/value belongs to key) - python

I can't figure out how to check if the answer is right.
import random
elements = {"Co":"cobaltum",
"C":"Carboneum"}
question = random.choice(list(elements.keys()))
print(question)
answer=input("What is the full name of this element? ")

Perhaps:
if answer == elements[question]:
print("you're right!")
...I think that's what you're asking. Basically you can access the value of a key in a dictionary like
myDict[key] # value

Related

Extracting a string from a tuple in Python

I am trying to make a dictionary of sorts using tuples. The idea is to store a word along with its description in a tuple. The tuple then goes into a list. After that, I'm supposed to be able to look up the meaning of a word in the dictionary by typing the word I want a description of.
My problem is to extract only the description part of the tuple from the list and print only that based on what word the user wants to look up. I do have a function that seems to work for making the tuples and storing them in the list but I think that function also is wrong.
This is as far as I have been able to come:
def tuples():
dictionary = []
while True:
print("\n--- Menu for dictionary ---\n Choose 1 to insert a word\n Choose 2 to lookup a word\n Choose 3 to quit\n")
answer = input("Write your answer here: ")
if answer == "1":
insert(dictionary)
elif answer == "2":
lookup(dictionary)
elif answer == "3":
break
else:
print("\nTry again!\n")
def insert(dictionary):
word = input("What word would you like to add: ")
des = input("Type a description of that word: ")
info = (word, des)
dictionary.append(info)
def lookup(dictionary):
word = input("What word do you want to lookup: ")
place = dictionary.index(word)
print("\nDescription of", word,":", dictionary[place], "\n")
Similar to the other answer, this example loops through the list of tuples examining the word part of the tuple to get to the description part. It differs in a number of respects, but the most important difference is that it uses tuple unpacking versus subscripting to get the contents of the tuple. To illustrate the key concepts I left out the user input part.
Note: If the list of tuples was long enough, you would want to consider sorting it and using something like the the bisect standard library to more efficiently search it and update it.
Example:
dictionary = [("cat", "Four legs, scratches."), ("dog", "Four legs, wags."), ("gerbil", "Four legs, kangaroo-like.")]
def find_description(dictionary, search_term):
# Note use of automatic tuple "unpacking"
for word, description in dictionary:
if word == search_term:
print(f"Description of {word}: {description}")
break
else: # no-break
print(f"Could not find {search_term} in dictionary.")
find_description(dictionary, "gerbil")
find_description(dictionary, "hamster")
Output:
Description of gerbil: Four legs, kangaroo-like.
Could not find hamster in dictionary.
I think you can achieve what you are trying to do by modifying your lookup function
to use a generator expression to search the dictionary list for the query. I got your example to work with the following modification to lookup():
def lookup(dictionary):
word = input("What word do you want to lookup: ")
place = next((i for i, v in enumerate(dictionary) if v[0] == word), None)
print("\nDescription of", word,":", dictionary[place][1], "\n")
If you are concerned with runtime I would recommend abstracting out the (word, des) tuple out to a class that could be hashable such that you can use a dictionary as your dictionary, utilizing the faster lookup. This also would solve the issue of duplicate entries.

How do you delete a key from a dictionary by only using an value entered by a user

I am a student trying to complete a task on a online course and I can't find a efficient way to solve this problem.
problem:
Ask the user to enter 4 of their favorite foods and store them in a dictionary so that they are indexed with numbers starting from 1. Display the dictionary in full showing the index number an the item. Ask them which they want to get rid of and remove it from the list. Sort the remaining data and display it.
I have tried many possible solutions but none of them seem to work. This is what i have done so far (python 3.8):
foodcount=0
foods={1:0 ,2:0 ,3:0 ,4: 0}
while foodcount<4:
food_choice=str(input('enter one of your favourite foods'))
foodcount += 1
foods[foodcount] = food_choice
least_fav=str(input('choos a food to delete'))
nowant=foods.index[least_fav]
del foods[nowant]
print(foods)
foods.sort(key=str)
for key,value in foods:
print(foods(key,value))
I am not sure if I am misinterpreting this question but the main problem I am having is once the user enters the food they would like to delete (assume that the always enters a input that is in the dict) I can't delete the key the the food is in (can't delete the key and value). I know i have to index something but still really not sure
Thanks in advance
dict does not support .index so you are going to have to use a for loop to iterate through a dictionary.
foodcount=0
foods={1:0 ,2:0 ,3:0 ,4: 0}
while foodcount<4:
food_choice=str(input('enter one of your favourite foods'))
foodcount += 1
foods[foodcount] = food_choice
least_fav=str(input('choose a food to delete'))
for key, value in foods.items():
if value == least_fav:
foods.pop(key)
break
print(foods)
for key,value in foods.items():
print(key,value)
you already showed you know how to use a for loop to loop through the dictionary but you have to change it up a bit. If you use "foods" in a for loop it will only iterate through the keys, so 1, 2, 3, 4. if you use "foods.items()" it sets key to the keys and value to the values, which I assume you wanted.
Next you just tell it that if the value of a key is the same as what the user entered you use .pop which deletes a key:value pair based on the value.
other than that you just make sure you break when you are done so you don't get an error and use your (revised) print loop at the bottom to get the keys and values.
Hope this helps!
If your dictionary has the foods as keys it is easier to work with them. This will work even if they misswrite the name (won't happen anything if they write it wrong):
foodcount=0
foods = []
while foodcount<4:
food_choice=str(input('enter one of your favourite foods'))
foodcount += 1
foods.append(food_choice)
foods_dict = dict(zip(foods,[1,2,3,4]))
least_fav=str(input('choos a food to delete'))
foods_dict.pop(least_fav, None)
Output:
Foods: a,b,c,d
Least favorite: b
print(foods_dict)
{'a': 1, 'c': 3, 'd': 4}

Making John, john and JOHN mean the same variable in python lists?

My question is this.
How do I make it so users can not make a new user_name John if JOHN or john are already in use.
Can I make user_name.upper() = user_name.lower() or something like that.
These names are been iterated through a loop of current_users. I want the loop to detect current users and disallow the use of a name if it has already been used in its upper() or title() forms.
Edit: If possible could I get the most 'pythonic' way of doing this. Thanks.
You can use a list comprehension if you do not need to loop through the current_users for anything else:
if user_name.lower() in [user.lower() for user in current_users]:
# user_name already taken
This would be the same as doing:
lower_current_users = list()
for user in current_users:
lower_current_users.append(user.lower())
if user_name.lower() in lower_current_users:
# user_name already taken
As you can see, a list comprehension requires fewer lines of code and is very useful for this type of thing.
Alternatively, a normal for loop can be used if you need to check more than one thing:
for user in current_users:
if user_name.lower() == user.lower():
# user_name already taken
You can use a lambda (a small anonymous little function) and make all your whole list lower case, and then compare that the the lower new_name. If it's new, add it, if not, don't.
name_list = ["John", "Sam", "Joe"]
new_name = "jOhN"
if new_name.lower() in [x.lower() for x in name_list]:
print("nope")
else:
print("new name, add it!")
name_list.append(new_name)
print (name_list)
for username in current_user_names:
if ip_username.lower() == username.lower():
Flag = 1
print ‘match found’
else:
Flag = 0
current_user_names.append(username)
Or simply just while you add your usernames add them in lower case.
your_userlist.append(username.lower())
And you can simply use the IN keyword to check
if current_user.lower() IN your_userlist:
Use the code below
existing_users = ["John","tilak","RAMESH","SidDDu"]
while True:
name = raw_input("Enter a name: ")
for i in existing_users:
if name.lower() == i.lower():
print "Name Already exists!Please choose another"
else:
existing_users.append(name)

Iterate through dictionary values?

Hey everyone I'm trying to write a program in Python that acts as a quiz game. I made a dictionary at the beginning of the program that contains the values the user will be quizzed on. Its set up like so:
PIX0 = {"QVGA":"320x240", "VGA":"640x480", "SVGA":"800x600"}
So I defined a function that uses a for loop to iterate through the dictionary keys and asks for input from the user, and compares the user input to the value matched with the key.
for key in PIX0:
NUM = input("What is the Resolution of %s?" % key)
if NUM == PIX0[key]:
print ("Nice Job!")
count = count + 1
else:
print("I'm sorry but thats wrong. The correct answer was: %s." % PIX0[key] )
This is working fine output looks like this:
What is the Resolution of Full HD? 1920x1080
Nice Job!
What is the Resolution of VGA? 640x480
Nice Job!
So what I would like to be able to do is have a separate function that asks the question the other way, providing the user with the resolution numbers and having the user enter the name of the display standard. So I want to make a for loop but I don't really know how to (or if you even can) iterate over the values in the dictionary and ask the user to input the keys.
I'd like to have output that looks something like this:
Which standard has a resolution of 1920x1080? Full HD
Nice Job!
What standard has a resolution of 640x480? VGA
Nice Job!
I've tried playing with for value in PIX0.values() and thats allowed me to iterate through the dictionary values, but I don't know how to use that to "check" the user answers against the dictionary keys. If anyone could help it would be appreciated.
EDIT: Sorry I'm using Python3.
Depending on your version:
Python 2.x:
for key, val in PIX0.iteritems():
NUM = input("Which standard has a resolution of {!r}?".format(val))
if NUM == key:
print ("Nice Job!")
count = count + 1
else:
print("I'm sorry but thats wrong. The correct answer was: {!r}.".format(key))
Python 3.x:
for key, val in PIX0.items():
NUM = input("Which standard has a resolution of {!r}?".format(val))
if NUM == key:
print ("Nice Job!")
count = count + 1
else:
print("I'm sorry but thats wrong. The correct answer was: {!r}.".format(key))
You should also get in the habit of using the new string formatting syntax ({} instead of % operator) from PEP 3101:
https://www.python.org/dev/peps/pep-3101/
You could search for the corresponding key or you could "invert" the dictionary, but considering how you use it, it would be best if you just iterated over key/value pairs in the first place, which you can do with items(). Then you have both directly in variables and don't need a lookup at all:
for key, value in PIX0.items():
NUM = input("What is the Resolution of %s?" % key)
if NUM == value:
You can of course use that both ways then.
Or if you don't actually need the dictionary for something else, you could ditch the dictionary and have an ordinary list of pairs.
You can just look for the value that corresponds with the key and then check if the input is equal to the key.
for key in PIX0:
NUM = input("Which standard has a resolution of %s " % PIX0[key])
if NUM == key:
Also, you will have to change the last line to fit in, so it will print the key instead of the value if you get the wrong answer.
print("I'm sorry but thats wrong. The correct answer was: %s." % key )
Also, I would recommend using str.format for string formatting instead of the % syntax.
Your full code should look like this (after adding in string formatting)
PIX0 = {"QVGA":"320x240", "VGA":"640x480", "SVGA":"800x600"}
for key in PIX0:
NUM = input("Which standard has a resolution of {}".format(PIX0[key]))
if NUM == key:
print ("Nice Job!")
count = count + 1
else:
print("I'm sorry but that's wrong. The correct answer was: {}.".format(key))
If all your values are unique, you can make a reverse dictionary:
PIXO_reverse = {v: k for k, v in PIX0.items()}
Result:
>>> PIXO_reverse
{'320x240': 'QVGA', '640x480': 'VGA', '800x600': 'SVGA'}
Now you can use the same logic as before.
Create the opposite dictionary:
PIX1 = {}
for key in PIX0.keys():
PIX1[PIX0.get(key)] = key
Then run the same code on this dictionary instead (using PIX1 instead of PIX0).
BTW, I'm not sure about Python 3, but in Python 2 you need to use raw_input instead of input.

index error while running a loop over list contents

I have a list like this:
my_array= ["*","device",":","xyz"], ["+","asd","=","10","pdf","=","6"],
["+","dsa","=","1","pqa","=","2","dga","=","12"], ["*"]
What I want to do is:
define('device','xyz')
define('asd','10')
define('pdf','6')
define('dsa','1')
define('pqa','2')
define('dga','12')
The way I approached is:
i=0
while i < len(my_array):
if my_array[i][0]=="*":
print("'",my_array[i][1],"'","'",my_array[i][3:],"'")
elif my_array[i][0]=="+":
print("'",my_array[i][1],"'","'",my_array[i][3],"'")
if my_array[i][4]=="\D":
print("'",my_array[i][4],"'","'",my_array[i][6],"'")
elif my_array[i][7]=="\D":
print("'",my_array[i][7],"'","'",my_array[i][9],"'")
i=i+1
But doing this, I get index error. I know where the problem is, but I cannot fix it with my very bad programming brain. Can someone help me on this?
First review problem seems in
if my_array[i][0]=="*":
print("'",my_array[i][1],"'","'",my_array[i][3:],"'")
because last element in your my_array is ['*'] and it has no other elements and u are trying to access my_array['*'][1] and its give index error.
You have to remove that element or add members who fulfill element index requirement.
Hard-coding the indices is a sure sign you're doing something wrong - the items in my_array have variable lengths, so some of your indices inevitably fail. I think what you want is something like:
for command in my_array:
if command[0] in ("*", "+"):
for start in range(1, len(command), 3):
assignment = command[start:start+3]
if assignment[1] in ("=", ":"):
print assignment[0], assignment[2]
It is worth noting, however, that you seem to be attempting to write a file parser. Although this code solves this specific problem, it is likely that your overall approach could be improved.
With the assumption, that every key in your list has a value attached to it(e.g. there are no two asterisk following after each other) you can make some simplifications:
We'll read the first value as a key of a new dict and the second item as the value.
With the newly tidied up dict(d) you can continue to work easily e.g. in a for loop:
array=["*","device",":","xyz"], ["+","asd","=","10","pdf","=","6"],
["+","dsa","=","1","pqa","=","2","dga","=","12"], ["*"]
d = {}
for list in array:
new_key = None
for item in list:
if item in ['*',':','+','=']: continue
if new_key == None:
new_key = item
else:
d[new_key] = item
new_key = None
for key in d:
define(key,d[key])

Categories