Explanation for filling a dictionary with user input - python

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?

Related

Confused on dictionary input example in Python Crash Course

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).

Sending SMS to a list of names, numbers dictionary while also carrying over another key value

Alright so I have a function that should allow me to send multiple SMS to a list of dictionaries within my script. So for example my list of dictionaries looks like
users = [{'User': entry.name.value, 'Number':entry.telephoneNumber.value, 'days':days_left.days}]
and I have a function within a class that will send an sms to each phone number in the list of dictionaries, but within each sms it will find and attach the right name, and days left.
def send_sms():
client = Client(twilio_account_sid, twilio_auth_token)
for d in users:
for name, number in d.items():
message = client.messages.create(
to=number,
from_=twilio_from_phone_number,
body=f'Hello {name}, you have {days_left.days} days left to reset your password. -IT')
print(message.sid)
self.app.log.info(f'Sent {len(users)} sms msgs to users')
send_sms()
so I am a little stock on the logic within the function. I need to be able to access individual names and days left. For reference:
days_left = (pwd_expire_date.astimezone(tz=None) - today)
days left = each users password expiration time - todays date(leaving how many days they have left)
This is a script to access AD and check if a users password is within 30,15,3 days and if it is send them SMS and Email notification. This is my first real task as an engineer and it is a little more than I understand. I know my for loop logic isn't right because that just grabs key, value. But how would I iterate through my list of dictionaries and pull out the appropriate values? PS(The body is just an example). I am not sure if you will have a MWE because this is connecting to my AD, but I think my issue is with basic python syntax. Thanks for any help. If this is a dumb question I am sorry.
My expected outcome is :
Each user receive a SMS to their specific number, with their name and days till they have to reset their password.
'Hello John, you have 15 days left to reset your password. -IT'
Twilio developer evangelist here.
I think your code is mostly right! Your loop through the users, for d in users: seems correct to me. At this point you should find that d is the dictionary of user data.
I think your issue is the use of for name, number in d.items():. Instead of trying to get the data out of an array of tuples that .items() returns is going to be hard. Instead, you can access the data from the dictionary directly using square brackets (or the get method) and the name of the field, like d["Username"]. Try this:
def send_sms():
client = Client(twilio_account_sid, twilio_auth_token)
for d in users:
message = client.messages.create(
to=d["Number"],
from_=twilio_from_phone_number,
body=f'Hello {d["Username"]}, you have {d["days"]} days left to reset your password. -IT')
print(message.sid)
self.app.log.info(f'Sent {len(users)} sms msgs to users')
send_sms()

Check for a specific value in a table python

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

Python: How to require an input to correspond with a previous input?

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.

My program is not producing an output, why is this?

I recently just asked a question on SO regarding on how to turn a text file into a dictionary on Python, it worked until I made a slight adjustment to the code as I want to compare the key to a word in a string, and if the key was the same as the word, it would print the corresponding value, however no output is printed, why is this?
def answerInput():
print("Hello, how may I help you with your mobile device")
a = input("Please enter your query below\n")
return a
def solution(answer):
string = answer
my_dict = {}
with open("Dictionary.txt") as f:
for line in f:
key, value = line.strip("\n").split(maxsplit=1)
my_dict[key] = value
for word in string.split():
if word == my_dict[key]:
print(value)
process = 0
answer = answerInput()
solution(answer)
If anyone it helps, my text file is as goes:
battery Have you tried charging your phone? You may need to replace your battery.
dead Have you tried charging your phone? You may need to replace your battery.
sound Your volume may be on 0 or your speakers may be broken, try using earphones.
screen Your screen may be dead, you may need a replacement.
touchID You may need to wipe the fingerprint scanner, try again.
microphone You may need to replace your microphone.
Read the file into my_dict dictionary first, then do lookups into it (your current code as posted reads the file as it does the lookups). Also, compare the words of the user's answer to the keys, not values of the my_dict dictionary (as your code does).
All of this also means that the code should have 3 parts, perhaps something similar to the solution below.
def read_dictionary(in_file):
my_dict = {}
with open(in_file) as f:
for line in f:
key, value = line.strip('\n').split(maxsplit=1)
my_dict[key] = value
return my_dict
def read_query():
print('Hello, how may I help you with your mobile device')
return input('Please enter your query below\n').strip('\n')
def solve(query, my_dict):
for word in query.split():
if word in my_dict:
print(my_dict[word])
return
return
my_dict = read_dictionary('Dictionary.txt')
query = read_query()
solve(query, my_dict)
you're trying to compare the variable 'answer' to the variable 'key', not the value stored in my_dict[key].
also, I'd suggest you use .lower() such as: if answer.lower() == key
so you'd be able to process user responses even if they are in upper case letters
I'm not sure if this is the way you want it to work and configparser usage is a little different but I kinda like the way it can work here.
import configparser
config = configparser.ConfigParser()
config.read("conf.ini", encoding="utf-8")
def answerInput():
print("Hello, how may I help you with your mobile device")
a = input("Please enter your query below\n")
return a
answer = answerInput()
print(config.get("Answers", answer))
conf.ini file in the same directory:
[Answers]
battery = Have you tried charging your phone? You may need to replace your battery.
dead = Have you tried charging your phone? You may need to replace your battery.
sound = Your volume may be on 0 or your speakers may be broken, try using earphones.
screen = Your screen may be dead, you may need a replacement.
touchID = You may need to wipe the fingerprint scanner, try again.
microphone = You may need to replace your microphone.
This is obviously depending if you already have a huge list of those key value pairs or you are gonna be creating ones. If you are creating ones, this might be a nice strucured way to do it.

Categories

Resources