How do I fix this syntax error caused by a colon? - python

I'm creating a class that simulates an ATM and I don't know why I'm getting a syntax error on the colon between 'id' and 'zwhite'.
import pickle
import sys
import os
class ATM(object):
def __init__(self):
self.users = ['id':'zwhite','name':'Zack White','pin':'4431','balance':845,
'id':'jzimmerman','name':'John Zimmerman','pin':'6780','balance':59,
'id':'cbenson','Carly Benson','pin':'8991','balance':720]
def check(self,ids):
print Your balance: +str(ids['balance'])
def withdraw(self,person):
for i in self.users:
if i['id'] == person['id']:
print Your balance: +str(i['balance'])

I suspect you want to be creating a list of dictionaries. This would make sense of the duplicated keys on separate lines:
Try:
self.users = [{'id':'zwhite','name':'Zack White','pin':'4431','balance':845},
{'id':'jzimmerman','name':'John Zimmerman','pin':'6780','balance':59},
{'id':'cbenson','name':'Carly Benson','pin':'8991','balance':720}]
I also added the 'name' key for the value 'Carly Benson' in the last row.

You should use a dictionary, not a list.
self.users = {...}

The square brackets ([ ]) are used to create a list. List are used to store elements only. You cannot store keys and values. You can just store elements like [1,2,3,"ab","cd",3.23] etc. If you want to store the data in key-value pairs, then you'll have to use dictionary. By looking at the code, I think you know the concept of dictionary but you're confused with creating dictionary. Curly braces ({ }) are used to create dictionary. Just change the square brackets to curly braces

Related

Python Refactoring - Changing Variable Type and Value Within a Loop

I'm working on automating some word and PDF documents that need to be updated on a certain cadence.
The way I'm doing this is using dictionaries that replace variables within word documents.
My code works but because my area is not tech savvy I'm using an excel file so people can replace the values in that file whenever they need to update the documents.
I was also successful on pulling the dictionary key and values from excel but I'm trying to refactor this code which is repetitive. Here is an excerpt with 2 of the 7 dictionaries I'm creating:
dic = pd.read_excel('test.xlsx',"AD")
AD = dict(zip(dic.Key,dic.Value))
dic = pd.read_excel('test.xlsx',"RSM")
RSM = dict(zip(dic.Key,dic.Value))
I'm trying to refactor this so I can run it all within a single loop and trying something like this:
import pandas as pd
AD = "AD"
RSM = "RSM"
groups = [AD, RSM]
for item in groups:
dic = pd.read_excel('test.xlsx',item)
item = dict(zip(dic.Key,dic.Value))
So I'm basically first using the variable as a string to call the excel tab within the read_excel method and then I want to replace that same variable to become the output dictionary.
When I print item within the loop I do get the correct dictionaries but I'm not able to output a variable that stores each dictionary that the loop creates.
Any help would be appreciated.
Thanks!
You're almost there, you can just have a dictionary of dictionaries:
import pandas as pd
groups = ['AD', 'RSM']
dicts = {}
for item in groups:
dic = pd.read_excel('test.xlsx', item)
dicts[item] = dict(zip(dic.Key, dic.Value))
Now you can just access them like this:
print(dicts['AD']['some key'])
The values of a dictionary can be anything, including other dictionaries. Keys of dictionaries can be many things as well, as long as they're hashable, and strings are a common choice of course - and the names of your groups are just that.
Also note that I removed the variables named AD and RSM. You don't really achieve anything by having variables that are named after the string value they are assigned. It only serves to be able to leave off the quotes where you use the values, but it creates an additional indirection that serves no purpose.
If you don't even need the list of groups, but just want groups to be the actual dictionaries:
import pandas as pd
groups = {}
for item in ['AD', 'RSM']:
dic = pd.read_excel('test.xlsx', item)
groups[item] = dict(zip(dic.Key, dic.Value))
The problem is that you assign the result to the item variable and not to an entry in the list.
A simple fix would be to use a dictionary instead of a list to save the reult, eg
import pandas as pd
AD = "AD"
RSM = "RSM"
groups = {AD: None, RSM: None}
for item in groups.keys():
dic = pd.read_excel('test.xlsx',item)
groups[item] = dict(zip(dic.Key,dic.Value))
My suggestion would be to use an overall dictionary to track your work and also to save the results there. I refactored your code slightly to this:
import pandas as pd
groups = dict.fromkeys(('AD', 'RSM')) # setup main dict containing dicts
for item in groups:
dic = pd.read_excel('test.xlsx', item)
groups[item] = dict(zip(dic.Key, dic.Value)) # store individual dict
There's no need for your global constants that are used only once, so I removed those. I also added some spaces to help your Python code conform with PEP-8, the global standard style guide.
Now you can access each dictionary as you like, for example, groups['AD'].

How to add a value to a dictionary that has a duplicate key

I have this problem where I would like to add a value to a dictionary but the key is duplicate.
I would like the key to to hold a list with multiple values
this is what I have tried
def storingPassword():
username=("bob")#key,
password=("PASSWROD1")#value
allpasswords={
"jeff":"jeff 123 ",
"bob" : "bob 123"
}
if username not in allpasswords:
allpasswords[username]=password
else:
allpasswords[username].append(password)
return allpasswords
but i keep getting this error
"AttributeError: 'str' object has no attribute 'append'"
I expect a output something like this;
"jeff":"jeff 123 ",
"bob" : ["bob 123","PASSWORD1"]
That's because the value in your allpasswords dict is a string and you are trying to treat it like a list. Why are you trying to make your data structure complex with few values as list and few as string? I recommend to convert everything to list for a simpler logic.
Hence your code should be like this:
allpasswords={
"jeff": ["jeff 123 "],
"bob" : ["bob 123"]
}
allpasswords[username].append(password)
Instead of using dict object, you can use collections.defaultdict. It will let you define a dict with default value as list. So you don't need to even explicitly initialise value of new key as list. For example:
from collections import defaultdict
my_dict = defaultdict(list)
my_dict['new_key'].append('new_value')
# dictionary will hold the value:
# {'new_key': ['new_value']})
Initiate your dictionary entry with a list instead of just a string.
allpasswords[username] = [password] # List containing a single password
You will then be able to append to it.
(Having some entries contain a string while others contain a list of strings is best avoided - when it is time to look them up or print them, you would have to check each time whether it is a list or string.)

Adding a new dictionary item to a nested dictionary

cities={
'city1':{
'name':'sydney',
'country':'australia',
'desc':'beautiful'
},
'city2':{
'name':'toronto',
'country':'canada',
'desc':'amazing',
}
}
cities['city3']:"{'name':'Tokyo','country':'japan','desc':'lots of earthquakes’}"
for keys,values in cities.items():
print(f"{keys}--->{values}”)
This is my code. I am new to python and learning dictionaries as of now. I am trying to add a dictionary to an existing dictionary but it doesn’t work. I have no errors and still only get the first two cities info. I think my syntax must be wrong. Can anyone help me with this please>?
Output:
Try to change your insertion code to:
cities['city3'] = {'name':'Tokyo','country':'japan','desc':'lots of earthquakes'}
You probably don't want to add it as a string, so leave away the quatation marks. Furthermore, there is an erroneous quatation mark at the end of the description.
Use Chainmap from collections, it chains all dictionary into one.
from collections import ChainMap
city3 = {'city3': {'name':'Tokyo','country':'japan','desc':'lots of earthquakes'}}
cities = ChainMap(cities,city3)
print(dict(cities))

how to create a dictionary using lists in a python class?

I am trying to create a portfolio class. I want to zip my two lists into a dictionary but when a i try to print it out, it is empty(even though my lists are not). Am i missing something??
import numpy as np
class Portfolio(object):
"""description of class"""
array_of_stock_prices=[]
array_of_stock_names=[]
#create a dictionary of stocks
stocks=dict(zip(array_of_stock_names,array_of_stock_prices))
def __init__(self):
print()
def AddStock(self,stock_ticker,stock_price):
self.array_of_stock_names.append(stock_ticker)
self.array_of_stock_prices.append(stock_price)
def printObject(self):
for key,value in self.stocks.items():
print(key,value)
port1=Portfolio()
port1.AddStock('AApl',100)
port1.printObject()
You create the dictionary only once, with empty lists. If you want to keep it up to date, put that line of code after every extension of the lists (in the end of AddStock), and keep this dictionary as an attribute of self, like
self.stocks = dict(zip(self.array_of_stock_names, self.array_of_stock_prices))

Error with Python dictionary: str object has no attribute append

I am writing code in python.
My input line is "all/DT remaining/VBG all/NNS of/IN "
I want to create a dictionary with one key and multiple values
For example - all:[DT,NNS]
groupPairsByKey={}
Code:
for line in fileIn:
lineLength=len(line)
words=line[0:lineLength-1].split(' ')
for word in words:
wordPair=word.split('/')
if wordPair[0] in groupPairsByKey:
groupPairsByKey[wordPair[0]].append(wordPair[1])
<getting error here>
else:
groupPairsByKey[wordPair[0]] = [wordPair[1]]
Your problem is that groupPairsByKey[wordPair[0]] is not a list, but a string!
Before appending value to groupPairsByKey['all'], you need to make the value a list.
Your solution is already correct, it works perfectly in my case. Try to make sure that groupPairsByKey is a completely empty dictionary.
By the way, this is what i tried:
>>> words = "all/DT remaining/VBG all/NNS of/IN".split
>>> for word in words:
wordPair = word.split('/')
if wordPair[0] in groupPairsByKey:
groupPairsByKey[wordPair[0]].append(wordPair[1])
else:
groupPairsByKey[wordPair[0]] = [wordPair[1]]
>>> groupPairsByKey
{'of': ['IN'], 'remaining': ['VBG'], 'all': ['DT', 'NNS']}
>>>
Also, if your code is formatted like the one you posted here, you'll get an indentationError.
Hope this helps!
Although it looks to me like you should be getting an IndentationError, if you are getting the message
str object has no attribute append
then it means
groupPairsByKey[wordPair[0]]
is a str, and strs do not have an append method.
The code you posted does not show how
groupPairsByKey[wordPair[0]]
could have a str value. Perhaps put
if wordPair[0] in groupPairsByKey:
if isinstance(groupPairsByKey[wordPair[0]], basestring):
print('{}: {}'.format(*wordPair))
raise Hell
into your code to help track down the culprit.
You could also simplify your code by using a collections.defaultdict:
import collections
groupPairsByKey = collections.defaultdict(list)
for line in fileIn:
lineLength=len(line)
words=line[0:lineLength-1].split(' ')
for word in words:
wordPair=word.split('/')
groupPairsByKey[wordPair[0]].append(wordPair[1])
When you access a defaultdict with a missing key, the factory function -- in this case list -- is called and the returned value is used as the associated value in the defaultdict. Thus, a new key-value pair is automatically inserted into the defaultdict whenever it encounters a missing key. Since the default value is always a list, you won't run into the error
str object has no attribute append anymore -- unless you have
code which reassigns an old key-value pair to have a new value which is a str.
You can do:
my_dict["all"] = my_string.split('/')
in Python,

Categories