I am working my way through Python Crash Course, and in Chapter 8 the author gives the following code as an example for filling a dictionary with user input. I am confused in the step where he stores the responses into the dictionary, as to my eye it looks as though he is only saving one piece of , "response" which is immutable data to the "responses" dictionary under the key "name". I am missing how both the name input and response input are put into the dictionary.
It seems to make no sense to me, but that is what I have loved about this journey so far, finding sense in seeming nonsense. Thank you for helping demystify this world for me.
responses = {}
# Set a flag to indicate that polling is active.
polling_active = True
while polling_active:
#Prompt for the person's name and response.
name = input("\nWhat is your name? ")
response = input("Which mountain would you like to climb someday? ")
#Store the response in the dictionary:
responses[name] = response
#Find out if anyone else is going to take the poll.
repeat = input("Would you like to let another person respond? (yes/no) ")
if repeat == 'no':
polling_active = False
#Polling is complete. Show the results.
print("\n--- Poll Results ---")
for name, response in responses.items():
print(name + " would like to climb " + response + ".")
The thing with dictionaries is that you can change the value of the key like this: dictionary[key] = value. If the key doesn't exist it will simply create a new key. You don't need any function like append which is used for lists. The line where you wrote responses[name] = response works because it stays in a while loop. After the loop runs again it asks another input and replaces the old name with a new name and old response with a new response. In conclusion, name and response is added every time the loop runs if the name is not already in the dictionary. If the name is there then it will simply change its value response if that is different from the old one.
Does this answer your question?
name and response are variables names that are filled with the inputted data, let's say 'John' and 'Kalimanjaro'.
Now, 'John' and 'Kalimanjaro' are indeed immutable, but that doesn't mean you can't replace the values stored in name and response in the next loop. You can assign a new value, maybe also immutable, to name if you want.
One possible source of confusion could be that you started learning dictionaries using statements like responses['John'] = 'Kalimanjaro', where both key and value were strings. Now you are doing responses[name] = response (no quotes around name and response). So you create a key called whatever was stored in name and a value with whatever was stored in response.
If in the next iteration the value of name is replaced by, let's say 'Maria' and response becomes 'Andes', the new responses[name] = response will be equivalent to responses['Maria'] = 'Andes'.
In the most basic explanation, dictionaries associates an arbitrary value at an arbitrary key. So, what the author is actually doing is associating the user's response with their name. The author does this by using the name as a key and the response as a value. Using dictionaries like this is fairly common.
If you want to retrieve a value in the array, you must know it key. However, you can retrieve all key and value pairs with dictionary.items(). This way, the author can get those two associated pieces of data (the name and the response).
Related
I am trying to make a login script check for a verified email the check script is
#check for verification
while True:
if "'emailVerified': True" in accountinfo:
break
else:
print("Your email has not been verified! Please verify it with the new link we have sent.")
auth.send_email_verification(user['idToken'])
menu()
The value in the table I am trying to find is
'emailVerified': True
It keeps saying it can not find it though the value is there. How do I make it look for that? Am I doing it wrong?
It looks like you are trying to use the string "'emailVerified': True" as a key to the accountinfo dictionary object (representing an account's info I think).
The think the best way to do it would be to do this:
while True:
if accountinfo['users'][0]['emailVerified']:
break
else:
print("Your email has not been verified! Please verify it with the new link we have sent.")
auth.send_email_verification(user['idToken'])
menu()
Although this is quite bad and the structure of your accountinfo object is convoluted. I think you should either split it up into two objects or just unpack the lists into key value pairs for the entire accountinfo object. I would avoid having to use [0] (or having to use [i]) to index the List within the dictionary object, which has ANOTHER dictionary in it! That is very confusing hierarchy of python objects.
You should try to change the accountinfo object to allow this:
while True:
if accountinfo['emailVerified']:
break
else:
print("Your email has not been verified! Please verify it with the new link we have sent.")
auth.send_email_verification(user['idToken'])
menu()
Your user validation logic is not very clear. But if you simply ask why emailVerified: True is in accountinfo, but if "'emailVerified': True" in accountinfo always gets False. The answer is they are different types. The left is a string, the right is a dictionary(or json).
Can you try this function:
def is_any_user_email_verified(accountinfo):
return any(u for u in accountinfo['users'] if u['emailVerified'])
# usage:
if is_any_user_email_verified(accountinfo):
break
all. Python newbie here.
Simply-put here is my basic idea:
I want to create a "Login" feature where people must input a valid username from a preset tuple.
Next, once a valid name is entered, they will be asked to enter the corresponding code name, which is saved to a dictionary. (I have a feeling that I am over-complicating this, or maybe the dictionary is the wrong idea entirely, so any advice on how to simplify would be great).
real_names = ("JD", "JM" "JC")
player_ids = {"JD":"Arrow","JM":"Bullet","JC":"Blade"}
while True:
# user must input a name from the real_names tuple
name = input("User unidentified. Please input your name: ")
# if username is not in tuple, rerun script
if not name in real_names:
print("Invalid username detected")
continue
print(f"Positive ID! Welcome, {name}")
break
The above code works just fine. But next, I want to make a new input that requires the player ID to match the previously input name. In Pseudo-code, something like this:
# While True Loop:
id = input("Please confirm user Code Name: ")
#ID must correspond to keyword in dictionary
if ID value does not match username Keyword:
print("Invalid ID")
continue
print("Identity confirmed!")
break
Am I on the right path? If so, how would I syntax the second part? If the dictionary is the wrong idea entirely, please provide a good alternative. Many thanks!
player_ids[name] is the value you're looking for. So, you want something like this:
if id != player_ids[name]:
print("invalid ID")
Also, the dictionary already keeps track of player names, so you don't need the real_names tuple.
This previous answer works perfect, because you are looking up the value based on the key from a dictionary. Finally, one little tip, it's always good practice to avoid naming variables after reserved variables and keywords, that is to say, use another variable name just in case you are going to use to use the id() function again in the program.
Could I get an explanation for the line of code responses[name] = response? I dont really understand how that line stores the user input in a dictionary. (This is an exercise for the Python crash course book if that's why the code looks odd.)
responses = {}
# Set a flag to indicate that polling is active
polling_active = True
while polling_active:
# Prompt for the person's name and response
name = input("\nWhat is your name? ")
response = input("Which mountain would you climb one day? ")
# Store the responses in a dictionary
responses[name] = response
#Find out if anyone else is going to take the poll
repeat = input("Would you like to let another person respond? (yes / no) ")
if repeat == 'no':
polling_active = False
# polling is complete, show the results
print("\n --- Poll results --- ")
for name, response in responses.items():
print(f"{name.title()} would like to climb {response.title()}")
responses is the dictionary. When you loop through the while loop, the name is getting stored as the key in the dictionary and the response is getting stored as the value. So basically this
responses[name] = response
is saying, take the name that is given, store it as the key, and take the response and store it as the value, each iteration through the loop.
Dictionaries in themselves are a way to assign a key to an item then be able to look up items using those keys. In simple terms it would be like an address to an house. The address is the identifier to the house.
Lets look at some code to break down responses[name] = response
Starting with an empty dictionary
responses = {}
looking at the keys in the dictionary
responses.keys()
dict_keys([])
We can see there are no keys (or addresses from the earlier example) because it return and empty list []
How do you add a key to dictionary that already exists? One option is to add it using the bracket syntax.
In this example we will add the key (or address) '123 main street' which is a string with the value of 'Our Nice Private Home' which is also a string.
responses['123 main street'] = 'Our Nice Private Home'
Now what do the keys look like?
responses.keys()
dict_keys(['123 main street'])
You can see the key '123 main street' was added to the dictionary.
In your example responses[name] = response
responses is the dictionary, name contains what the user entered after the prompt What is your name? and response contains what the user entered after the prompt Which mountain would you climb one day?
Please help!
Well, first of all, I will explain what this should do. I'm trying to store users and servers from discord in a list (users that use the bot and servers in which the bot is in) with the id.
for example:
class User(object):
name = ""
uid = 0
Now, all discord id are very long and I want to store lots of users and servers in my list (one list for each one) but suppose that I get 10.000 users in my list, and I want to get the last one (without knowing it's the last one), this would take a lot of time. Instead, I thought that I could make a directory system for storing users in the list and finding it quickly. This is how it works:
I can get the id easily so imagine my id is 12345.
Now I convert it into a string using python str(id) function and I store it in a variable, strId.
For each digit of the list, I use it as an index for the users list, like this:
The User() is where the user is stored
users_list = [[[], [[], [], [[], [], [], [User()]]]]]
actual_dir = 0
for digit in strId:
actual_dir = digit
user = actual_dir[0]
And that's how I reach the user (or something like that)
Now, here is where my problem is. I know I can get the user easily by getting the user by id, but when I want to save the changes, I should do something like users_list[1][2][3][4][5] = changed_user_variable, but how far I know I cannot do something like list[1] += [2]
Is there any way to reach the user and save the changes?
Thanks in advance
You can use a python dictionary with the user id as the key and the user object as the value. I ran a test on my own computer and found that finding 100 000 random users in a dictionary with 10 million users only took 0.3s. This method is much simpler and I would guess it's just as fast, if not faster.
You can create a dictionary and add users with:
users = {}
users[userID] = some_user
(many other ways of doing this)
by using a dictionary you can easily change a user's field by:
users[userID].some_field = "Some value"
or overwrite the same way you add users in the first place.
I have a discord bot that constantly stores a message sent by the user. I want to save these message somewhere, and then when the bot is called, I want to randomly send one of the messages I've saved. Or show them a list of all the messages i've saved.
Here is the code:
#client.command()
async def quote(ctx,user:discord.Member,*,message):
color=discord.Color(value=0x9C2A00)
async for messages in ctx.channel.history(limit=1):
pass
em=discord.Embed(color=color,title=message,description=f'-{user}, [original](https://discordapp.com/channels/{messages.guild.id}/{messages.channel.id}/{messages.id})')
await ctx.send(embed=em)
I want to keep saving the 'em' variable. Or i guess more specifically the title and description of the em variable.
I tried storing the variable em in a list and that worked! However, it only stored the last value of em. I want to store each value of em.
What I did was as follows:
em=#the code
em_list=[]
em_list.append(em)
However, each time a new value is given to 'em' the old one in the list is overwritten with the new value. I want to store each value, not just the latest one.
Again, please refer to any tutorial on list handling. In particular
# Do this once: initialize your list
em_list=[]
...
# In your code that executes multiple time:
em=#the code
em_list.append(copy(em))
# hHen that is all done ...
for em in em_list:
# Do whatever you want with each element in the list
print(em)
There are two convenient ways to store the data: list or dictionary.
In case it is a key:value pair of data that you are storing, you will be better off with a dictionary. In a dictionary, the key is what points to the value. Each value has a key with which it can be located within a dictionary. So, in case you want to store the data as a key-value pair, where the key can be the 'user' name or the 'message' name, while the value can be the 'em' variable.
em_dict = {}
em_dict[message] = em
# 'em' can then be used to store another item, and that item can be stored in
# the em_dict with a different message or user key
Whereas if you simply want to store only the 'em's content, irrespective of which 'user' or 'message' title it corresponds to, you can simply create a list of all the variables that 'em' stores temporarily:
em_list = []
em_list.append(em)
# Then change the value of em and store it using the list's append() method.
Both the dictionary and the list can be used to store the 'em' values using a for loop
You need to copy the variable. Otherwise every time it is updated all its references will point to the new value.
em_list = []
# when em updates:
em2 = em
em_list.append(em2)
# when em updates again:
em3 = em
em_list.append(em3)
The better way to do it is to not store the values in a variable at all. You can just append them to a list directly, without a name:
em_list = []
em_list.append(1)
em_list.append(2)
em_list.append(3)