Python: Unable to add a new key:value to a dictionary - python

I am making a dictionary for storing tests and their grades for different students.
def tests():
test1 = {'craig':88, 'jeanie':100}
test2 = {'craig':85, 'jeanie':95}
test3 = {'craig':80, 'jeanie':98}
return test1,test2,test3
def actions(test1,test2,test3):
test1.update({'john':95})
test1.update({'chris':92})
test1.update({'charles',100})
test2.update({'john':100})
test2.update({'chris':96})
test2.update({'charles',98})
test3.update({'john':97})
test3.update({'chris':100})
test3.update({'charles',94})
return test1,test2,test3
def main():
one,two,three = tests()
one,two,three = actions(one,two,three)
print (test1,test2,test3)
main()
However, when I try to append a new key:value to my dicts two errors come up:
First:
Traceback (most recent call last):
File "C:\file.py", line 26, in <module>
main()
File "C:\file.py", line 24, in main
one,two,three = actions(one,two,three)
File "C:\file.py", line 14, in actions
test1.update({'charles',100})
TypeError: cannot convert dictionary update sequence element #0 to a sequence
Second:
Traceback (most recent call last):
File "C:\file.py", line 26, in <module>
main()
File "C:\file.py", line 24, in main
one,two,three = actions(one,two,three)
File "C:\file.py", line 14, in actions
test1.update({'charles',100})
ValueError: dictionary update sequence element #0 has length 7; 2 is required
If I run it over and over again, sometimes the first error comes up, sometimes the other.
I do not want any imports such as collections.

test1.update({'charles',100})
is updating the dict with a set not a dict, which it clearly cannot use to update ... instead of sets pass it dicts
test1.update({'charles':100})
just to demonstrate
{1,2,3,4,4,5,6} # a set that will contain 1,2,3,4,5,6
{1:2,3:4,4:5} # a dict with 3 elements dict(1=2,3=4,4=5)

If I understand your need you need add new values not update and for that operation you need change update for setdefault method. I have tested on Aptana Studio that code:
def tests():
test1 = {'craig':88, 'jeanie':100}
test2 = {'craig':85, 'jeanie':95}
test3 = {'craig':80, 'jeanie':98}
return test1,test2,test3
def actions(test1,test2,test3):
test1.setdefault('john',95)
test1.setdefault('chris',92)
test1.setdefault('charles',100)
test2.setdefault('john',100)
test2.setdefault('chris',96)
test2.setdefault('charles',98)
test3.setdefault('john',97)
test3.setdefault('chris',100)
test3.setdefault('charles',94)
return test1,test2,test3
def main():
one,two,three = tests()
one,two,three = actions(one,two,three)
print(one,two,three)
main()
and get response:
one - {'john': 95, 'charles': 100, 'jeanie': 100, 'chris': 92, 'craig': 88}
two - {'john': 100, 'charles': 98, 'jeanie': 95, 'chris': 96, 'craig': 85}
three - {'john': 97, 'charles': 94, 'jeanie': 98, 'chris': 100, 'craig': 80}
Your problem is that update search one dictionary with key for update your value and not insert but setdefault insert new pair key:value with that syntax case not exists and return the value for one key case her exists.
Good work for you,

See answer here:
Add new keys to a dictionary?
To update:
#### Inserting/Updating value ####
data['a']=1 # updates if 'a' exists, else adds 'a'
# OR #
data.update({'a':1})
# OR #
data.update(dict(a=1))
# OR #
data.update(a=1)
# OR #
data.update([(a,1)])
Instead of this:
test3.update({'charles',94})

Related

Python Dict: TypeError: list indices must be integers, not str

This piece of code is from a script that obtains the PDB (Protein Data Bank) code which contain the UniProt code store in a dictionary: DDomainSeq.
This is a sample of DDomainSeq Dic:
{'3.30.67.10': ['G3GAK5', 'I3QCE1', 'G3EN69', 'K4LBV0', 'Q2XWS4', 'D6MQ73', 'F1D844', 'Q8JTJ9', 'H9U1G9', 'B1PNF1', 'B3F7E1', 'Q9J0E6', 'K4LBK6', 'Q2XRW4', 'D0EPQ6', 'D3U0G6', 'Q8QMF3', 'J9PQ44', 'B9W116', 'Q2XRW9', 'I3QCH7', 'K7R4A7', 'I7B1H2', 'B1PNH0', 'I3QCD9', 'Q82861', 'I3QC33', 'Q2XRJ4', 'E3UMQ4', 'B9V561', 'Q8BE43', 'Q80QJ9', 'E0YAP9'], '2.60.98.10': ['C9WJC0', 'B3TN06', 'Q9IZI7', 'Q9WDA0', 'A9LIM6', 'C5MSX3', 'Q6Q6Q1', 'Q3LFV0', 'E5RCU8', 'I6XG39', 'G5EJD7', 'D3X8F0', 'Q2XRV6', 'D0QXC4', 'I7EMG2', 'A4UIW9', 'Q89283', 'H9M657', 'F2YLD8', 'Q2YGV6', 'D6MQ23', 'G9F8Y6', 'G8G189', 'H8Y6K8', 'E3UMP9', 'Q91AG4', 'I3QCA4', 'A4K4T3', 'H6VBW8', 'D8FSI8', 'D0TYZ3', 'I3QCM1', 'H6VBX9', 'C0JZP9', 'C6ZE88', 'A1BY35', 'I7A3V7', 'Q2XRZ1', 'A5YBK7', 'Q66463', 'C3V004', 'Q6YG48', 'Q2ESB0', 'H1ZYK5', 'Q00P61', 'E2IZW1', 'D0VF46', 'K4IYH8', 'Q9IJX6', 'Q87046', 'Q9WB77', 'C7T0M1', 'I3QC70', 'E2IGI0', 'Q32ZL8', 'C8CKT7', 'D6MM36', 'Q3LFN6', 'F5AXV2', 'I6PGU1', 'B9W157', 'K7PP62', 'Q3Y6G7', 'Q6YFX6', 'C9WPK5', 'G9IBD9', 'G9DR11', 'C1KKF7', 'I6WJM3', 'K7PPW7', 'Q3S2G1', 'Q6WP68', 'H2D5H7', 'H2D5I3', 'K7QRY5', 'Q9WLZ8', 'F5AXW1', 'Q8JTJ2', 'E3UMM2', 'B9VHE4', 'B6E979', 'Q2YH31', 'A7TUC9', 'D3X8C3', 'H2D5I2', 'B6EBW6', 'F2WS10', 'Q2YH68', 'C1KKE8', 'B0LCR1''A3GPY8']}
Each one of the elements within each key are use to search for a PDB file found in the PDBSum Data base.
PDBSumWWW = urllib.urlopen("https://www.ebi.ac.uk/thornton-srv/databases/pdbsum/data/seqdata.dat")
PDBSum = PDBSumWWW.read().splitlines()
PDBSumWWW.close()
This is the code I use for this:
for domain in dDomainSeq.keys():
print domain
PDB = []
for uni in dDomainSeq[domain]:
for i in range(len(PDBSum)):
if "SWS_ID" in PDBSum[i]:
str = PDBSum[i]
splited = str.split()
if uni in splited[2]:
PDB.append(splited[0])
print PDB
print len(PDB)
PDBSum[domain]=PDB
However after loading all PDB-UniProt Code matches the first key "3.30.67.10" it reveals the following error:
Traceback (most recent call last):
File "/Users/ThePoet/Dropbox/MBID/MSc Summer Project/Program/SeqPDBSum.py", line 57, in <module>
main()
File "/Users/ThePoet/Dropbox/MBID/MSc Summer Project/Program/SeqPDBSum.py", line 45, in main
PDBSum[domain]=PDB
TypeError: list indices must be integers, not str
To get a dictionary try
varofdictionary = {}
PDBSum is a list, so you should create an empty dictionary and append to that.

Pyspotify - periodic "the track cannot be played error"

I have a problem with pyspotify. I'm trying to search for an artist name, get a list of their top tracks and then play one of them. This is my code segment:
search_string = "artist:"+artist_to_find
result = session.search(search_string)
result.load()
print result.track_total
browser = result.artists[0].browse()
browser.load()
print browser.tophit_tracks
for track in browser.tophit_tracks:
print track.name, track
toptracks = browser.tophit_tracks
print "error check"
if toptracks!=-1:
print "------------------"
tracktoplay=choice(toptracks)
rand = randint(0,10)
print "random track number = %s" %rand
tracktoplay = browser.tophit_tracks[rand]
print tracktoplay.link
print tracktoplay.name
print "------------------"
session.player.load(tracktoplay)
session.player.play()
I frequently call this code without the previous track finishing. Perodically (every few tracks) I get the following error:
random track number = 7
spotify:track:6vQN2a9QSgWcm74KEZYfDL
Take A Chance On Me
------------------
Traceback (most recent call last):
File "../jj.py", line 146, in <module>
app.run()
File "../jj.py", line 116, in run
conversation.handleForever()
File "/home/mh/Projects/jjo/client/conversation.py", line 44, in handleForever
listen(self)
File "/home/mh/Projects/jjo/client/new_play.py", line 110, in listen
play(self,response)
File "/home/mh/Projects/jjo/client/new_play.py", line 194, in play
session.player.load(tracktoplay)
File "/usr/local/lib/python2.7/dist-packages/spotify/player.py", line 45, in load
self._session._sp_session, track._sp_track))
File "/usr/local/lib/python2.7/dist-packages/spotify/error.py", line 30, in maybe_raise
raise LibError(error_type)
spotify.error.LibError: The track cannot be played
Can anyone advise on what I'm doing wrong?
Thanks
I don't have experiece on pyspotify, but I was looking at it out of curiosity.
If I was you I would check the PlayerState is LOADED before I call play()
Hope it helps.

Using Linked lists and patterns in python

Trying to write a function that will iterate over the linked list, sum up all of the odd numbers and then display the sum. Here is what I have so far:
from List import *
def main():
array = eval(input("Give me an array of numbers: "))
ArrayToList(array)
print(array[0])
print(array[1])
print(array[2])
print(array[3])
print(sumOdds(array))
def isOdd(x):
return x % 2 != 0
def sumOdds(array):
if (array == None):
return 0
elif (isOdd(head(array))):
return head(array) + sumOdds(tail(array))
else:
return sumOdds(tail(array))
main()
I can't get it to actually print the sum though. Can anybody help me out with that?
Here is the output of the program when I run it:
$ python3 1.py
Give me an array of numbers: [11, 5, 3, 51]
Traceback (most recent call last):
File "1.py", line 22, in <module>
main()
File "1.py", line 10, in main
print(sumOdds(array))
File "1.py", line 19, in sumOdds
return head(array) + sumOdds(tail(array))
File "1.py", line 18, in sumOdds
elif (isOdd(head(array))):
File "/Users/~/cs150/practice3/friday/List.py", line 34, in head
return NodeValue(items)
File "/Users/~/cs150/practice3/friday/List.py", line 12, in NodeValue
def NodeValue(n): return n[0]
TypeError: 'int' object is not subscriptable
In Python you iterate through a list like this:
list_of_numbers = [1,4,3,7,5,8,3,7,24,23,76]
sum_of_odds = 0
for number in list_of_numbers:
# now you check for odds
if isOdd(number):
sum_of_odds = sum_of_odds + number
print(sum_of_odds)
List is also a module only on your computer. I do not know what is inside. Therefore, I can not help you after ArrayToList(array).

Reading data from JSON file with Python

I have a datra structure like this:
"37_7009": [
{
"viewport_dimensions": {"width": 1583, "height": 798},
"mouse_position": {"y": 1147, "x": 841},
"node_data_attrs": {"groupid": "id_FW13-e052-7009-08", "rankgroupid": "rank_37"}
}
]
with:
with gzip.GzipFile(args.file,'rb') as gzf:
all_hovers = json.load(gzf)
How can I read out the node_data_attrs values?
for cords in all_hovers[userID]:
x = cords["mouse_position"]["x"]
y = cords["mouse_position"]["y"]
viewport_x = cords["viewport_dimensions"]["width"]
viewport_y = cords["viewport_dimensions"]["height"]
data_attrs = cords["node_data_attrs"]["groupid"]
I get the following traceback:
Traceback (most recent call last):
File "opdracht2-3.py", line 86, in <module>
main()
File "opdracht2-3.py", line 66, in main
print cords["node_data_attrs"]["groupid"]
KeyError: 'groupid'
That doesn't work for reading the data... any suggestions?
Your code works just fine, it just appears that at least some of your data doesn't have a groupid key.
Use .get() to work around this:
for cords in all_hovers[userID]:
x = cords["mouse_position"]["x"]
y = cords["mouse_position"]["y"]
viewport_x = cords["viewport_dimensions"]["width"]
viewport_y = cords["viewport_dimensions"]["height"]
data_attrs = cords["node_data_attrs"].get("groupid")
This sets data_attrs to None if the key is missing. You can set it to a different default by passing in a second argument to dict.get():
data_attrs = cords["node_data_attrs"].get("groupid", 'default value')
Given the following sequence of numbers inserted into an AVL tree, indicate if the insertion results in no-rotate, rotate right, rotate left, double rotate left, and double rotate right.
9,8,7,6,2,3,4,5,11,1,12,23,24
List the BST tree in level order if no rotations are  done:
Root: 
L1:
L2:
...
List the AVL tree in level order if rotations are  done:
For the toolbar, press ALT+F10 (PC) or ALT+FN+F10 (Mac).

Using method as a dictionary value

class Inventory(object):
def __init__(self):
self.inventory = {
'cash': 500,
'paycheck': 1,
'savings': 1000,
'current_car': 0,
'possible_cars': ['Chevy', 'Honda', 'BMW'],
'car_cost': [0, 100, 200],
'current_house': 0,
'possible_houses': ['apartment','townhouse','suite'],
'house_cost': [0, 150, 300],
'status': self.status()
}
def status(self):
while self.inventory['cash'] + self.inventory['savings'] > 0:
return True
I'm currently working through "Learn Python the Hard Way", on Exercise 45. I've created a class to list the items relevant to my game, I've stored these keys and values in a dictionary under my init method. Where I'm having trouble is within my last key and it's value - the 'status' key.
What I want for this value to do is reference my status method, which I've set to return true as long as my player has a positive sum of money (other portions of my game will reference .inventory['status'] to check its truth before they execute. Now I've done quick two line proof-of-concept codes to verify that it's possible to use a function as a value - where I'm getting hung up on is how to implement this within a class, specifically when my dictionary is within init.
My error:
Traceback (most recent call last):
File "ex45file1.py", line 151, in <module>
my_inv = Inventory() #TEST
File "ex45file1.py", line 80, in __init__
'status': status()
NameError: global name 'status' is not defined
Where am I going wrong here?
First, that isn't the error that your code produces. In your version you have 'status': status() but on SO you wrote 'status': self.status(). In any case, if you fix that you still have a problem,
AttributeError: 'Inventory' object has no attribute 'inventory'
The reason you get that error is because Python is in the process of defining your inventory attribute yet you are call status which must refer to inventory to give a return value.
You don't even want to be calling the function and saving the return value in the dictionary since that won't allow you to use it dynamically. You should change it such that you don't invoke but just save the reference.
class Inventory(object):
def __init__(self):
self.inventory = {
'cash': 500,
'paycheck': 1,
'savings': 1000,
'current_car': 0,
'possible_cars': ['Chevy', 'Honda', 'BMW'],
'car_cost': [0, 100, 200],
'current_house': 0,
'possible_houses': ['apartment','townhouse','suite'],
'house_cost': [0, 150, 300],
'status': self.status # <--- don't use parens ()
}
And just call the method like,
>>> my_inventory = Inventory()
>>> my_inventory.inventory['status']()
True
I got a different error, but I believe the solution would be the same:
class Inventory(object):
def __init__(self):
self.inventory = {
'cash': 500,
'paycheck': 1,
'savings': 1000,
'current_car': 0,
'possible_cars': ['Chevy', 'Honda', 'BMW'],
'car_cost': [0, 100, 200],
'current_house': 0,
'possible_houses': ['apartment','townhouse','suite'],
'house_cost': [0, 150, 300],
}
self.inventory['status'] = self.status()
def status(self):
while self.inventory['cash'] + self.inventory['savings'] > 0:
return True
My error was complaining about inventory not being defined in status().
I tried copying & pasting your code into my Python interpreter and I get a different error:
>>> inv = new Inventory()
File "<stdin>", line 1
inv = new Inventory()
^
SyntaxError: invalid syntax
>>> inv = Inventory()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 13, in __init__
File "<stdin>", line 16, in status
AttributeError: 'Inventory' object has no attribute 'inventory'
The problem is that you have a cyclic dependency here between inventory and status. You use status to define inventory, but status needs to read inventory before it can return... See the problem?

Categories

Resources