http://www.learnpython.org/Serialization_using_JSON_and_pickle
Here are the instructions:
The aim of this exercise is to print out the JSON string with key-value pair "Me" : 800 added to it.
And below is the starting code, which we should modify.
#Exercise fix this function, so it adds the given name and salary pair to the json it returns
def add_employee(jsonSalaries, name, salary):
# Add your code here
return jsonSalaries
#Test code - shouldn't need to be modified
originalJsonSalaries = '{"Alfred" : 300, "Jane" : 301 }'
newJsonSalaries = add_employee(originalJsonSalaries, "Me", 800)
print(newJsonSalaries)
I'm completely lost. The JSON lesson was brief, at best. The issue I seem to be running in to here is that orginalJsonSalaries is defined as a string (containing all sort of unnecessary symbols like brackets. In fact, I think if the single quotes surrounding its definition were removed, originalJsonSalaries would be a dictionary and this would be a lot easier. But as it stands, how can I append "Me" and 800 to the string and still maintain the dictionary-like formatting?
And yes, I'm very very new to coding. The only other language I know is tcl.
EDIT:
OK, thanks to the answers, I figured out I was being dense and I wrote this code:
import json
#Exercise fix this function, so it adds the given name and salary pair to the json it returns
def add_employee(jsonSalaries, name, salary):
# Add your code here
jsonSalaries = json.loads(jsonSalaries)
jsonSalaries["Me"] = 800
return jsonSalaries
#Test code - shouldn't need to be modified
originalJsonSalaries = '{"Alfred" : 300, "Jane" : 301 }'
newJsonSalaries = add_employee(originalJsonSalaries, "Me", 800)
print(newJsonSalaries)
This does not work. For whatever reason, the original dictionary keys are formatted as unicode (I don't know where that happened), so when I print out the dictionary, the "u" flag is shown:
{u'Jane': 301, 'Me': 800, u'Alfred': 300}
I have tried using dict.pop() to replace the key ( dict("Jane") = dict.pop(u"Jane") ) but that just brings up SyntaxError: can't assign to function call
Is my original solution incorrect, or is this some annoying formatting issue and how to resolve it?
The page you linked to says exactly how to do this:
In order to use the json module, it must first be imported:
import json
[...]
To load JSON back to a data structure, use the "loads" method. This method takes a string and turns it back into the json object datastructure:
print json.loads(json_string)
They gave you a string (jsonSalaries). Use json.loads to turn it into a dictionary.
Your last question is a new question, but... When you print a dictionary like that you are just using the fact that python is nice enough to show you the contents of its variables in a meaningful way. To print the dictionary in your own format, you would want to iterate through the keys and print the key and value:
for k in newJsonSalaries:
print("Employee {0} makes {1}".format(k, newJsonSalaries[k]))
There are other problems in your code....
It is weird to load the JSON inside the add employee function. That should be separate...
Also, in your add_employee() function you are hardwired always to add the same values of Me and 800 instead of using the name and salary variables that are passed in, so that line should be:
jsonSalaries[name] = salary
Use this:
import json
def add_employee(jsonSalaries, name, salary):
# Add your code here
jsonSalaries = json.loads(jsonSalaries)
jsonSalaries[name] = salary
jsonSalaries = json.dumps(jsonSalaries)
return jsonSalaries
#Test code - shouldn't need to be modified
originalJsonSalaries = '{"Alfred" : 300, "Jane" : 301 }'
newJsonSalaries = add_employee(originalJsonSalaries, "Me", 800)
print(newJsonSalaries)
Add this before return jsonSalaries:
jsonSalaries = json.dumps(jsonSalaries)
Related
this is a dummy version of what a function returns. I would like to know how to extract
'the.email#addresi.want' and 'Nextstringiwant from:
{'blah': {'blah1': 'the.email#addresi.want', 'blah2': 'Nextstringiwant'}, 'blah3': {'-note-': 'blah4', 'blah5': 'blah6', 'blah7': 'blah#bleble.blah', 'blah8': 'blah9'}}
I honestly don't understand the purpose for {} brackets very well, or how to work with it. I cannot change the function that returns this. Please help me, i'm lost. My gut tells me that I should convert this into a normal list and just get the desired position within that list, but it returns this error.
My code:
brackets = function().split(sep=':')
brackets.to_list()
email=brackets[2]
string=brackets[3]
The error:
brackets = creds.split(sep=':')
AttributeError: 'dict' object has no attribute 'split'
Note:
This is exactly how the function returns the {} list, I only changed the values for simplicity sake.
I would really appreciate
As the error message indicates, split is an attribute/method for a string, not for a dictionary.
Your function returns a Python dictionary.
Given your function is called function, you can access the values like this:
result = function()
email_address = result["blah"]["blah1"] # this will be 'the.email#addresi.want'
next_string = result["blah"]["blah2"] # this will be 'Nextstringiwant'
You can get further information on Python dictionaries on this site:
https://realpython.com/python-dicts/
mydict = {
'blah': {'blah1': 'the.email#addresi.want',
'blah2': 'Nextstringiwant'},
'blah3': {'-note-': 'blah4',
'blah5': 'blah6',
'blah7':
'blah#bleble.blah',
'blah8': 'blah9'}
}
[k_ for k_ in mydict.get("blah", dict()).values()]
Output:
['the.email#addresi.want', 'Nextstringiwant']
{} mean json object in Python.
if that function return is string, you should use Json module of python to convert it to json object and access its properties. For example:
import json
obj = json.loads(str_above)
print (obj.blah.blah1)
print (obj.blah.blah2)
I am using a new script (a) to extract information from an old script (b) to create a new file (c). I am looking for an equal sign in the old script (b) and want to modify the modification script (a) to make it automated.
The string is
lev1tolev2 'from=e119-b3331l1 mappars="simp:180" targ=enceladus.bi.def.3 km=0.6 lat=(-71.5,90) lon=(220,360)'
It is written in python 3.
The current output is fixed at
cam2map from=e119-b3331l1 to=rsmap-x map=enc.Ink.map pixres=mpp defaultrange=MAP res=300 minlat=-71.5 maxlat=90 minlon=220 maxlon=360
Currently, I have the code able to export a string of 0.6 for all of the iterations of lev1tolev2, but each one of these is going to be different.
cam2map = Call("cam2map")
cam2map.kwargs["from"] = old_lev1tolev2.kwargs["from"]
cam2map.kwargs["to"] = "rsmap-x"
cam2map.kwargs["map"] = "enc.Ink.map"
cam2map.kwargs["pixres"] = "mpp"
cam2map.kwargs["defaultrange"] = "MAP"
**cam2map.kwargs["res"] = float((old_lev1tolev2.kwargs["km"]))**
cam2map.kwargs["minlat"] = lat[0]
cam2map.kwargs["maxlat"] = lat[1]
cam2map.kwargs["minlon"] = lon[0]
cam2map.kwargs["maxlon"] = lon[1]
I have two questions, why is this not converting the string to a float? And, why is this not iterating over all of the lev1tolev2 commands as everything else in the code does?
The full code is available here.
https://codeshare.io/G6drmk
The problem occurred at a different location in the code.
def escape_kw_value(value):
if not isinstance(value, str):
return value
elif (value.startswith(('"', "'")) and value.endswith(('"', "'"))):
return value
# TODO escape the quote with \" or \'
#if value.startswith(('"', "'")) or value.endswith(('"', "'")):
# return value
if " " in value:
value = '"{}"'.format(value)
return value
it doesn't seem to clear to me, but from you syntax here :
**cam2map.kwargs["res"] = float((old_lev1tolev2.kwargs["km"]))**
I'd bet that cam2map.kwargs["res"] is a dict, and you thought that it would convert every values in the dict, using the ** syntax. The float built-in should then be called in a loop over the elements of the dict, or possible a list-comprehension as here :
cam2map.kwargs["res"] = dict()
for key, value in old_lev1tolev2.kwars["res"].items():
cam2map.kwargs["res"][key] = float(value)
Edit :
Ok so, it seems you took the string 'from=e119-b3331l1 mappars="simp:180" targ=enceladus.bi.def.3 km=0.6 lat=(-71.5,90) lon=(220,360)'
And then thought that calling youstring.kwargs would give you a dict, but it won't, you can probably parse it to a dict first, using some lib, or, you use mystring.split('=') and then work your way to a dict first, like that:
output = dict()
for one_bit in lev_1_lev2.split(' '):
key, value = one_bit.split('=')
output[key] = value
I have the following line:
BL: {version: 2, revision: 1}
I want to parse it, so that I will get in one variable BL, and on the other, I will get
[[version, revision], [2,1]]
I have the following code:
for line in file:
print line.split(':',1)[0]; gives me the first word (BL)
print line.split(': ',1)[1]
data = json.loads(json.dumps(line.split(': ',1)[1]));
The problem is that data is not contained the data as variable, so when I do data[0], I get the char: {
What the correct way to do that?
Your JSON is not valid since it's keys are not valid (you probably want strings there).
To get around it you could do something hacky like:
# give value to non-string keys, to use in eval
version = "version"
revision = "revision"
d = eval(line.split(": ", 1)[1])
print [d.keys(), d.values()]
This requires you to know all keys in advance.
I recommend you fix your input-generating script instead.
I always avoid eval.
I have this in the HTML code:
"name":"London Street" dsakjhasfsa safksafas "north":"232","south":"12","east":"113","west":"9","curRoom":"110"
"name":"London Street" something asdgas dsakhdask "north":"0","south":"22","east":"131","west":"19","curRoom":"10"
I have try those with Regex, but somehow I'm failing somewhere.
\"name\":\"\A(...)\Z\"*?north\":\"(d+)\",\"south\":\"(\d+)\",east\":\"(\d+)\",west\":\"(\d+)\",curRoom\":\"(\d+)\"
\"name\":\"^(...)$\"*?north\":\"(\d+)\",\"south\":\"(\d+)\",east\":\"(\d+)\",west\":\"(\d+)\",currentRoom\":\"(d+)\"
\"name\":\"(...)+\"*?north\":\"(\d+)\",\"south\":\"(d+)\",east\":\"(d+)\",west\":\"(\d+)\",currentRoom\":\"(\d+)\"
And with those captures I want to create a dictionary like this:
{ key is current room, values [position 0: a list with neighbours [1,2,3], position 1 - the name of the room] }
I only know how to achieve this until a point, by assigning to variable the find for each room like this:
list_of_neighbours = []
number_south = re.findall('south\":\"(\d+)\"', url)
list_of_neighbours.append(number_south)
....
list_of_neighbours = [n,s,e,w]
dictionay ={}
for k, v in list_of_neighbours:
dictionay[k] = str(number_current_room)
dictionay[k].append(v)
but this doesnt add the room and have too many steps.
The questions are: Its possible to be a shorter version? and How can I fix the regex find?Thanks
You're trying to parse JSON with regex. Don't. JSON is basically already a dictionary, just stringified in a standard format.
Use the json module:
import json
rooms = json.loads(some_json_string)
I am trying to make arguments easier to manage in a script I am putting together, I figured I'd wrap a bunch of related items into a dictionary, and pass the dictionary out of the func. pulling out the objects as I need them.
One of these items is a regEx, and I'm struggling to figure out how to structure things properly so I can make it work.
In my initial code (no dictionary). I am 'hard' coding the regex into the parser:
def TopnTail(self,line):
topRegEx = re.compile(r'(<!--make_database header end-->)')
tailRegEx = re.compile(r'(<!--make_database footer start-->)')
searchdumpTopOfPage = topRegEx.search(line)
searchdumpBottomOfPage = tailRegEx.search(line)
if searchdumpTopOfPage:
self.__useLine=1
if searchdumpBottomOfPage:
self.__useLine=0
if self.__useLine == 1:
self.trimmedLines = self.trimmedLines + line + "\n"
return (self.trimmedLines)
in the 'dictionaried' version I want to set the variables in a setter:
def siteDetails():
baseDict = {'topRegex':'''re.compile(r'(<!--make_database header end-->)')''', 'tailRegex':'''re.compile(r'(<!--make_database footer start-->)')'''}
return baseDict
and get to the compiled regex:
def TopnTail(self,line):
topRegEx = baseDict['topRegex']
tailRegEx = baseDict['tailRegex']
searchdumpTopOfPage = topRegEx.search(line)
searchdumpBottomOfPage = tailRegEx.search(line)
if searchdumpTopOfPage:
self.__useLine=1
if searchdumpBottomOfPage:
self.__useLine=0
if self.__useLine == 1:
self.trimmedLines = self.trimmedLines + line + "\n"
return (self.trimmedLines)
but this throws an error:
line 35, in TopnTail
searchdumpTopOfPage = topRegEx.search(line)
AttributeError: 'str' object has no attribute 'search'
Which I am guessing means that its not actually made the regex object, but is still passing the string.
I appreciate that I am probably breaking about 3 cardinal rules here... but any suggestions about how to make it work would be fantastic... (also, first time playing with both classes and dictionaries... so please go easy if I've really messed up!)
How about this?
baseDict = {
'topRegex': r'(<!--make_database header end-->)'
}
And in your TopnTail method
topRegEx = re.compile(baseDict['topRegex'])
The problem with what you have, is that you're assigning a string to topRegEx that contains '''re.compile(r'(<!--make_database header end-->)')'''. Since str has no method search, you get an error.
It makes sense to still compile your regex, and use the returned object. Splitting the contents of the regex into a dict will help if you ever need to changes the regex pattern, or you want to define it dynamically.