I've recently just started learning Python and usally find answers to my problems online but can't seem to get the right solution for this one.
I created a dictionary with 3 contacts and i want to print 1 contact from the list using an if statement.
contacts = {
"John" : 938477566,
"Jack" : 938377264,
"Jill" : 947662781
}
if "John" in contacts:
print ("Contact details: %s %i" % contacts.items()[0])
This is the output I am looking for:
Contact details: John 938477566
But i keep getting this
Traceback (most recent call last):
File "C:\Users\user\Documents\asega\python\objectsclasses\exercise3.py", line 31, in
print ("Contact details: %s %i" % contacts.items()[0])
TypeError: 'dict_items' object does not support indexing
Thanks
contacts.items() returns pairs of key-value. In your case, that would be something like
(("John", 938477566), ("Jack", 938377264), ("Jill", 947662781))
Except that in python 3 this is like a generator and not a list. So you'd have to do list(contacts.items()) if you wanted to index it, which explains your error message. However, even if you did list(contacts.items())[0], as discussed above, you'd get the first pair of key-value.
What you're trying to do is fetch the value of a key if said key exists and contacts.get(key, value_if_key_doesnt_exist) does that for you.
contact = 'John'
# we use 0 for the default value because it's falsy,
# but you'd have to ensure that 0 wouldn't naturally occur in your values
# or any other falsy value, for that matter.
details = contacts.get(contact, 0)
if details:
print('Contact details: {} {}'.format(contact, details))
else:
print('Contact not found')
You can do like this. If you are sure that 'John' is in the dictionary, there is no need of if statement. In other way, you can write it.. your choice
contacts = {
"John" : 938477566,
"Jack" : 938377264,
"Jill" : 947662781
}
print("Contact details: %s %i" % ("John", contacts["John"]))
First of all its dictionary not a list , you can access the elements from a list by indexing , and it is not possible in dictionary,
you can access the elements by key
contacts = {
"John" : 938477566,
"Jack" : 938377264,
"Jill" : 947662781
}
for k,v in contacts.items():
print(k,v)
or
contacts['John'] you can access the value
No need to check in if condition just use get to get the corresponding value and return -1 if key is not present
contacts = {
"John" : 938477566,
"Jack" : 938377264,
"Jill" : 947662781
}
contacts.get('John',-1) # -1 will be returned if key is not found
Print formatting
name_to_search='John'
print("Contact details: %s %i" % (name_to_search, contacts.get(name_to_search,-1)))
Or
name_to_search='John'
print("Contact details: {} {}" .format(name_to_search, contacts.get(name_to_search,-1)))
Dictionaries do not support indexing so to print "John" you cant index it however the following code may word:
if "John" in contacts:
print("Contact details:","John",contacts["John"])
Hope it helps
Related
I have this Json, and I need a value from a rate.
"_id" : ObjectId("5addb57d0043582d48ba898a"),
"success" : true,
"timestamp" : 1524477784,
"base" : "EUR",
"date" : "2018-04-23",
"rates" : {
"AED" : 4.492662,
"AFN" : 85.576329,
"ALL" : 128.39508,
"AMD" : 586.837094,
"ANG" : 2.177608,
"AOA" : 267.092358,
"ARS" : 24.678283,
"AUD" : 1.602032,
"AWG" : 2.177639,
"AZN" : 2.079155,
"BAM" : 1.958775,
"BBD" : 2.446786,
"BDT" : 101.517146,
"BGN" : 1.943843,
"BHD" : 0.460968,
"NOK" : 9.626194,
}
And this is my Python code
import pymongo
uri = "mongodb://127.0.0.1:27017"
client = pymongo.MongoClient(uri)
database = client['db']
collection = database['currency']
collection2 = database['countries']
p = str(input('Insert the country: ')).capitalize()
if p=='Norway':
currency = collection.find_one({'NOK'})
print(currency)
I want to print the value inside de NOK, how can I do it?
Thanks in advance.
I think you can call it by :
currency = collection.find_one({"NOK"})
print(currency['rates']['NOK'])
What you're trying to do is fetch a value in a dictionary which is integrated inside of another dictionary. JSON returns are dictionaries.
I imagine that the collection variable contains the JSON return
One way of fetching this data is by calling the dictionary and telling it what key you want the dictionary to return, as the "NOK" key is in the "rates" key we will be calling the rates key first, then when the dictionary has returned the dictionary that contains the "NOK" key we will then pass the "NOK" key to that returned dictionary, so the code looks like this:
currency = collection["rates"]["NOK"]
Another way of doing this is using the for loop, it is a lot longer but may help you understand.
for key in collection:
if key == "rates":
for keyRates in JSON[key]:
if keyRates == "NOK":
currency = JSON[key][keyRates]
Hope this helps
what I'm trying to do is to update a MongoDB document with python and discord.py, but the code i've put doesn't work.
elif string2 == "add":
if string3 == "administrator":
cur = coll.find({"_id" : string1.id})
for doc in cur:
if doc["perm"] == "administrator":
await self.bot.say("Permission {} already found on db for user {}".format(string3, string1.name))
else:
db.users.update_one({"_id" : string1.id, "name" : string1.name, "perm" : "administrator"}, upsert=False)
await self.bot.say("Permissions updated on db for user {}".format(string1.name))
The following is the error.
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: update_one() missing 1 required positional argument: 'update'
Document from users collection:
_id: "191598787410526208"
name: "Stevyb0t"
perm: "administrator"
Essentially what other people have commented but with some formatting to make it more legible:
db.users.update_one(
{"_id": string1.id},
{"$set":
{"name": string1.name,
"perm": "administrator"
}})
I also removed upsert=False since that's the default value anyway so you don't need to specify it - though of course being explicit can be helpful
Edit: read all the comments, suggestion was already made to make accepted comment an answer so here it is. My answer is no different from that comment
If your id is a string, you may need to convert it to an ObjectId. Also, you can print the result of the update, and check success:
from bson import ObjectId
result = db.users.update_one(
{"_id": ObjectId(string1.id)},
{"$set":
{"name": string1.name,
"perm": "administrator"}
})
logger.debug('update result: {}'.format(result.raw_result))
if result.matched_count > 0:
# Success code goes here
pass
else:
# Failure code goes here
pass
Below is a little code snippet of a program i wrote which gets all instance ip and instance tags associated with it. I can easily do this using boto , my problem is if i find a AWS instance which is not having any tag name associated with it i want to display/write in file "ip UNKNOWN".
for reservation in reservations:
for instances in reservation.instances:
if instances.state == "running":
print instances.private_ip_address,instances.tags['Name']
fileCSV.write("%s %s\n"%(instances.private_ip_address,instances.tags['Name']))
if instances.state == "running" and 'Name' in instances.tags==' ':
print "%s %s" % (instances.private_ip_address,"UNKNOWN")
fileCSV.write("%s %s\n"%(instances.private_ip_address,"UNKNOWN")
This code prints something like this
192.124.121.17
192.124.121.11 squid-server
192.124.121.13 apache
I am expecting :
192.124.121.17 UNKNOWN
192.124.121.11 squid-server
192.124.121.13 apache
It seems that your code always catches the first if block.
You can try use the default value dictionary option in the get method.
Try this:
for reservation in reservations:
for instances in reservation.instances:
if instances.state == "running":
name = instances.tags["Name"] if instances.tags["Name"] != "" else "UNKNOWN"
print instances.private_ip_address,name
fileCSV.write("%s %s\n" % (instances.private_ip_address,name))
I didn't test this, but this should work.
for reservation in reservations:
for instances in reservation.instances:
if instances.state == "running":
print instances.private_ip_address, instances.tags['Name'] if instances.tags['Name'] else 'UNKNOWN'
So, I have been working on this simple Python program to get familiar with dictionaries. Basically, it works as a database which you can search in. If your entry is in the dictionary key, it brings up the information regarding the entry.
Family = {'Jim' : ['cool guy', 'has facial hair'],
'Ned' : ['hot stuff', ' wears Tees']}
query = input("Look up database on whom? > ")
for (name, info) in Family.items():
if name in query or name.lower() in query:
print("{} is {}".format(name, info))
This ^ works. However, when I tried to add an ELSE clause, to deal with non-existent entries, I get this.
else:
print ('Value not found!')
It prints the Value not found! many times before bringing up the value. If I try to add a 'go back to start' function it doesn't even bring up a registered value. I know this is because it is a loop and iterates over the dict one by one; so like 1)jim is true then 2) ned is false.
How do I improve this code to make it: -able to give an error about a non-existent entry and then restart the program. Thanks.
You will need to take care of case insensitivity in your code. Iterate through the list to ensure that the name exists before continuing:
Family = {'Jim' : ['cool guy', 'has facial hair'],
'Ned' : ['hot stuff', ' wears Tees']}
names = [name.lower() for name in Family]
def find(query):
if query.lower() in names:
info = [Family[n] for n in Family if n.lower() == query.lower()]
print('{} is {}'.format(
query, info
))
else:
print('{} not found'.format(query))
If you try it with the following sample:
find('Ned')
find('ned')
find('no ned')
You will get the following results:
Ned is [['hot stuff', ' wears Tees']]
ned is [['hot stuff', ' wears Tees']]
no ned not found
This is one way to do it:
Family = {'Jim' : ['cool guy', 'has facial hair'],
'Ned' : ['hot stuff', ' wears Tees']}
query = input("Look up database on whom? > ")
if query in Family.keys():
for (name, info) in Family.items():
if name in query or name.lower() in query:
print("{} is {}".format(name, info))
else:
print "Print Something - Not in Family"
If I were to search for a particular field in a mongodb collection my command would look something like this :
db.collection.find({ name : "John"})
If I want to make the field name dynamic, what would the command be?
Example:
db.collection.find({ <Dyanmic field variable> : <Value>})
Or is there an alternative to achieve this function?
Just use the variable in place of the dictionary key:
name = 'field_name'
db.collection.find({name : "John"})
Problem happens when you try without knowing data type. So in order to handle this , i used the following:
def multi_row_single_field_update(self, crieteriafldnm, crieteriafldtyp, updtfldnm, updtfldval, updtfldtyp):
try:
criteria = raw_input('\nEnter ' + crieteriafldnm + ' to update\n')
if crieteriafldtyp == 'int':
count = self.my_connect.find({str(crieteriafldnm): int(criteria)}).count()
else:
count = self.my_connect.find({str(crieteriafldnm): str(criteria)}).count()
updt_criteria = int(criteria) if updtfldtyp == 'int' else str(criteria)
self.my_connect.update(
{"$atomic": 1},
{str(crieteriafldnm): updt_criteria},
{"$set": {str(updtfldnm): str(updtfldval)}},
upsert=False, multi=True
)