Iterate through dictionary values? - python

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.

Related

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

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

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.

Is there anyway to automatically replace a section of a string in Python using a list of values?

If I have a string for example:
value = ("The value is at $500.00 today, check again please.")
And I have a table (df or list or something) of values, would it be possible to replace the "$500.00" at a set interval or whenever the script runs?
For example, if tomorrows value was $650.00 and so on, then without changing the string manually, could I keep replacing that segment of the string?
Cheers
There is multiple ways to solve your problem!
If you search for "Python string formatting" you will find a lot of examples etc.
value = "$500"
# one way
message = "The value is at %s today, check again please."
print(message % value)
# another way
message2 = "The value is at {0} today, check again please."
print(message2.format(value))
If your value is actually an int you can deal with it by converting your int to a str first.
value = 500
message = "The value is at $%s today, check again please."
print(message % str(value))
Python 3's f-Strings offer an even better syntax for this:
value = 500.00
message = f'The value is at ${value} today, check again please.'
print(message)
# output: The value is at $500.0 today, check again please.
Read more about Python3 fstrings here.
you could use str.format:
my_list = ['$500.00', '$600.00']
value = "The value is at {} today, check again please."
print(value.format(my_list[0]))
print(value.format(my_list[1]))
output:
The value is at $500.00 today, check again please.
The value is at $600.00 today, check again please.

How to sort input in a python age sorting program

I just made a program where you can type in your name and your age and it is supposed to sort people for their age from least to greatest. This is my code so far:
student_ages = {}
polling_for_age_active = True
while polling_for_age_active:
name = input("\nWhat is your name?")
response = input("How old are you?")
response = int()
student_ages[name] = response
repeat = input("Are there any other people to go? (yes\no)")
if repeat == 'no':
polling_for_age_active = False
print("\n----Ages(from least to greatest)----")
for name, response in student_ages.items():
response.sort()
print(name + " is " + response + " years old.")
When I run the code, the shell says that the int object cannot be sorted. Does anyone have any idea on how to fix this, or even improve it? Thanks.
You have to sort dictionary before for cycle. Inside for cycle type of variable response is string and you can't sort it.
Use something like this before for cycle
student_ages_sorted = sorted(student_ages.items(), key=lambda x: x[1])
You have a couple problems with your program. But the main design issue is that you are using a dictionary which is an unordered collection, and when you call response.sort() that is just trying to sort the individual item which doesn't do anything (you can't sort an integer).
What you can do instead is convert the dictionary items to a list which is sorted and then print that list out. We can store the items as tuples so it contains both the name and age data in the list.
sorted_list = sorted(student_ages.items(), key=lambda kv: kv[1]) # Makes a list of tuples sorted by the values
# Loop through sorted_list of tuples
for name, age in sorted_list:
print("{} is {} years old".format(name, age))
The other small problem with your program is that you are not properly taking in inputs and casting them to integers. Your call to int() is just going to return a 0 for all the ages.
To fix this you need to pass in the string as the parameter to the int() call so it converts the string to an int.
response = input("How old are you?")
response = int(response) # converts response to an int
You might want to put a try/except block around the conversion to an int to make sure that valid input was entered.

How do I define a function in python to choose a list.

I am trying to define a function to choose a list. I am writing a text adventure. I chose to represent the rooms as lists, with descriptions, monsters and so on.
Now I want to define a function get_room(id) to bring me the right room
Room1=[description1,monster1]
Room2=[description2,monster2]
I guess I could try to make a list of the lists and pick out the right room from that. But wouldn't that be slower?
I am new to programming so I would prefer if the solution doesn't involve classes if at all possible. I am using python 2.7.2.
You can make use of dictionary like this:
dict = {
'Room1' : ['description1','monster1'],
'Room2' : ['description2','monster2']
}
And than call them like:
print dict['Room1']
In my opinion you may declare your rooms in a unique variable:
valid_rooms = [['description1', 'monster1'],
['description2', 'monster2']]
So that it becomes easier for manipulating them.
Example for getting the user required position room:
var = raw_input("Please enter room number: ")
print("you entered"), var
selectedRoom = int(var)
print( "room index %d : %s" % (selectedRoom, valid_rooms[selectedRoom]))
Important: I strongly recommend you to test the int conversion of user input:
try:
myint = int(var)
except ValueError:
print("Sorry you do not enter a valid INTEGER!")
Remark: in the proposed scenario the function get_room() would be very simple (maybe not so useful)
def get_room(id):
return valid_rooms[id]
Note that in python 3.x raw_input was rename input.
If your room id is an integer you should use a list.
rooms = [Room1, Room2]
# I assume you want to assign your rooms a number from 1 to ...
def get_room(id):
return rooms[id - 1]
If your room is is not an integer but, for example, a string you should use a dictionary.
rooms = {
"room1": Room1,
"room2": Room2
}
def get_room(id):
return rooms[id]
In both cases, whenever you are using dictionary or list you should assume that access to the element is very fast. It is constant time which means that whenever dictionary/list has 10, 100, or 100000 elements selecting element from them will take the same amount of time.

Categories