converting a string to a line in a json file in python - python

I am trying to write a json file. The json file should look something like this -
{
"roster":[
{"name":"Andy","age":11},
{"name":"Nathan","age":10},
{"name":"Amy","age":12}
],
"links":[
{"source":1,"target":0,"value":1},
{"source":2,"target":0,"value":8},
{"source":3,"target":0,"value":10}
]
}
I am trying to create the roster part of the json by running through a for loop. In each iteration I am trying to append a line to the json file as follows -
wf = open("abc.json", "w")
wf.write('{\n"Roster":[\n')
for example in data:
name = ----some code here ----
group = ----some code here ----
wf.write('{"name":"'+name+'","group":'+group+'},\n')
I am getting a typeError - str and int objects cannot be concatenated. I understand why I am getting that error. I was just wondering if there is a better way to do it.

Python is Strongly Typed which means:
s = "foo"
s += 123
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objects
If you are adding strings (which btw are immutable) you need to "cast" the int to a str:
s = "foo"
s += str(123)

You are getting the error:
typeError - str and int objects cannot be concatenated
Because strings and integers cannot be concatenated.
Use str() to cast the integer to a string for concatenation instead.
wf.write('{"name":"'+name+'","group":'+str(group)+'},\n')
Or even better read up on string formatting in Python.
Or even more betterer read up on the Python JSON module.

Checking your string. You have to ensure string concatenation.
Try:
'{"name":"'+str(name)+'","group":'+str(group)+'},\n'
Or use json module to support you to output json file easily.
import json
output = {}
output['roster'] = [
{'name':'Andy', 'age':11},
{'name': 'Nathan', 'age': 10}
]
print(json.dumps(output))
Output:
{"roster": [{"name": "Andy", "age": 11}, {"name": "Nathan", "age": 10}]}

If you really want to write the json by hand, then the way to get around the concatenation error is to simply typecast the number to a string:
wf.write('{"name" : "'+str(name)+'","group":'+str(group)'},\n')
It would definitely be advisable to use the json module in python, it's a pretty great library.
For example, to get the json example you gave us:
{
"roster":[
{"name":"Andy","age":11},
{"name":"Nathan","age":10},
{"name":"Amy","age":12}
],
"links":[
{"source":1,"target":0,"value":1},
{"source":2,"target":0,"value":8},
{"source":3,"target":0,"value":10}
]
}
You could use the following:
import json
result = {}
result['roster'] = []
result['roster'].append({'name' : 'Andy', 'age' : 11})
result['roster'].append({'name' : 'Nathan', 'age' : 10})
result['roster'].append({'name' : 'Amy', 'age' : 12})
result['links'] = []
result['links'].append({'source' : 1, 'target' : 0, 'value' : 1})
...
(Obviously you would probably do this with a for loop instead of by hand in your program).
And then to convert this python dictionary to a json object you just use:
json.dumps(result)

Related

Python JSON encoding invalid json format

i've stucked, i have a json with symbols like ' in values and syntax with ' and "
Example mix double qoute and single qoutelink
json ={
'key': "val_'_ue",
'secondkey': 'value'
}
With json loads and json dumps i got a str type not a dict to iterate, any ideas how i get it fixed?
print(postParams)# = {'csrf-token': "TOKEN_INCLUDES_'_'_symbols", 'param2': 'params2value'}
jsn_dict2 = json.loads(json.dumps(postParams))
print(type(jsn_dict2)) # ERROR HERE why str and not dict
for key, val in jsn_dict2.items():
print("key="+str(key))
you dont need to dumps() an already string json data:
jsn_dict = json.loads(json.dumps(res))
should be :
jsn_dict = json.loads(res)
UPDATE
according to comments the data is looks like so:
postParams = "{'csrf-token': \"TOKEN_INCLUDES_'_'_symbols\", 'add-to-your-blog-submit-button': 'add-to-your-blog-submit-button'}"
so i found an library that can help damaged json string like this one:
first run :
pip install demjson
then this code can help you:
from demjson import decode
data = decode(postParams)
data
>>> {'csrf-token': "TOKEN_INCLUDES_'_'_symbols",
'add-to-your-blog-submit-button': 'add-to-your-blog-submit-button'}
In your json u have missed the "," comma separation between two keys. The actual structure of the JSON is
json_new ={
'key': "val_'_ue",
'secondkey': 'value'
}
use
json_actual=json.dumps(json_new)
to read,
json_read=json.loads(json_actual)

Convert a string with the name of a variable to a dictionary

I have a string which is little complex in that, it has some objects embedded as values. I need to convert them to proper dict or json.
foo = '{"Source": "my source", "Input": {"User_id": 18, "some_object": this_is_a_variable_actually}}'
Notice that the last key some_object has a value which is neither a string nor an int. Hence when I do a json.loads or ast.literal_eval, I am getting malformed string errors, and so Converting a String to Dictionary doesn't work.
I have no control over the source of the string.
Is it possible to convert such strings to dictionary
The result I need is a dict like this
dict = {
"Source" : "Good",
"object1": variable1,
"object2": variable2
}
The thing here is I wouldn't know what is variable1 or 2. There is no pattern here.
One point I want to mention here is that, If I can make the variables as just plain strings, that is also fine
For example,
dict = {
"Source" : "Good",
"object1": "variable1",
"object2": "variable2"
}
This will be good for my purpose. Thanks for all the answers.
It's a bit of a kludge using the demjson module which allows you to parse most of a somewhat non-confirming JSON syntax string and lists the errors... You can then use that to replace the invalid tokens found and put quotes around it just so it parses correctly, eg:
import demjson
import re
foo = '{"Source": "my source", "Input": {"User_id": 18, "some_object": this_is_a_variable_actually}}'
def f(json_str):
res = demjson.decode(json_str, strict=False, return_errors=True)
if not res.errors:
return res
for err in res.errors:
var = err.args[1]
json_str = re.sub(r'\b{}\b'.format(var), '"{}"'.format(var), json_str)
return demjson.decode(json_str, strict=False)
res = f(foo)
Gives you:
{'Input': {'User_id': 18, 'some_object': 'this_is_a_variable_actually'}, 'Source': 'my source'}
Note that while this should work in the example data presented, your mileage may vary if there's other nuisances in your input that require further munging.

How to parameterize JSON object in a Python script

I am writing a test in Python where i am specifying the JSON sting in a parameter as follows :
json = '...[{"MemberOperand":{
"AttributeName":"TEST",
"Comparison":"=",
"Value":"Test"}
}]...'
In this example i have the value as "Test" however i want to run the test with several values. Could you guys tell me how can i parameterize The values of "Value"?
You can construct proper JSON:
import json
the_value = 'Test'
data = [{"MemberOperand": {
"AttributeName":"TEST",
"Comparison":"=",
"Value": the_value}
}]
json_text = json.dumps(data)
This is regular dictionary (nested) formatted as string -
def changer(x):
import json
d=json.loads(json.loads(json.dumps('[{"MemberOperand":{"AttributeName":"TEST","Comparison":"=","Value":"Test"}}]')))
d[0]['MemberOperand']['AttributeName']=x
return d
print changer('New_TEST')
Output-
[{'MemberOperand': {'Comparison': '=', 'AttributeName': 'New_TEST', 'Value': 'Test'}}]
Add function which return you different json string all the time by provided value as parameter:
def get_mock_json(value='Test'):
return '...[{"MemberOperand":{"AttributeName":"TEST","Comparison":"=","Value":%s}}]...'%value
print get_mock_json('test')
print get_mock_json('ttttttest')

Update JSON objects with Python script for AWS

I have a bunch of JSON objects that I need to update in order to use the CLI for AWS.
Here is an example of the JSON format. I will need to update lbtest, lbtest-cookie-pol and 80 with different values.
{
"LoadBalancerName": "lbtest",
"PolicyName": "lbtest-cookie-pol",
"CookieExpirationPeriod":80
}
In some cases, there will be multiple values here for each Load Balancer Name.
The output will need to look like this:
{
"LoadBalancerName": "lbtest",
"PolicyName": "lbtest-cookie-pol",
"CookieExpirationPeriod":80
}
{
"LoadBalancerName": "lbtest",
"PolicyName": "lbtest-cookie-pol2",
"CookieExpirationPeriod":8080.
}
Suppose I had a CSV file with all these entries, what kind of python script can I write to loop through these and print out my JSON output? The part where I am having issues is the printing of the nested JSON object. print doesn't seem to like multiple lines or the curly braces that I have. Newbie here so I would appreciate any kind of solution.
you can use json.dumps method and it's options mentioned in documentations:
for example with using indent option you get this on python 2.7 :
>>> dictionary = {
"LoadBalancerName": "lbtest",
"PolicyName": "lbtest-cookie-pol",
"CookieExpirationPeriod":80 } #a dictionary object made from csv
>>> print dictionary
{'PolicyName': 'lbtest-cookie-pol', 'CookieExpirationPeriod': 80, 'LoadBalancerName': 'lbtest'}
>>> import json
>>> jobj = json.dumps(dictionary,indent=4, separators=(',', ': '))
>>> print jobj
{
"PolicyName": "lbtest-cookie-pol",
"CookieExpirationPeriod": 80,
"LoadBalancerName": "lbtest"
}
>>> f = open(r'jtest.txt','w') #save our json object to file
>>> json.dump(dictionary,fp,indent =4 , seperators = (',',': '))
>>> f.close()
>>> f = open(r'jtest.txt!','r') #read our object from file
>>> test = json.load(f)
>>> test
{u'PolicyName': u'lbtest-cookie-pol', u'CookieExpirationPeriod': 80, u'LoadBalancerName': u'lbtest'}
>>> dict(test)
{u'PolicyName': u'lbtest-cookie-pol', u'CookieExpirationPeriod': 80, u'LoadBalancerName': u'lbtest'}
here is how our file looks like:
jtest.txt file

Error in parsing .json file using Python

I am getting the following error. What does it mean?
AttributeError: 'bool' object has no attribute 'decode'
in code line : writer.writerow({k:v.decode('utf8') for k,v in dictionary.iteritems()})
My code looks like :
import json
import csv
def make_csv(data):
fname = "try.csv"
with open(fname,'wb') as outf:
dic_list = data['bookmarks']
dictionary = dic_list[0]
writer = csv.DictWriter(outf,fieldnames = sorted(dictionary.keys()), restval = "None", extrasaction = 'ignore')
writer.writeheader()
for dictionary in dic_list:
writer.writerow({k:v.decode('utf8') for k,v in dictionary.iteritems()})
return
def main():
fil = "readability.json"
f = open(fil,'rb')
data = json.loads(f.read())
print type(data)
make_csv(data)
The json file looks like :
{ "bookmarks" : [{..},{..} ..... {..}],
"recommendations" : [{..},{..}...{..}]
}
where [..] = list and {..} = dictionary
EDIT :
The above problem was solved, But when I ran the above code, The CSV file generated has some discrepancies. Some rows were pasted randomly i.e. under different headers in .csv file. Any suggestions?
Somewhere in your readability.json file you have an entry that's a boolean value, like true or false (in JSON), translated to the Python True and False objects.
You should not be using decode() in the first place, however, as json.loads() already produces Unicode values for strings.
Since this is Python 2, you want to encode your data, to UTF-8, instead. Convert your objects to unicode first:
writer.writerow({
k: unicode(v).encode('utf8')
for k ,v in dictionary.iteritems()
})
Converting existing Unicode strings to unicode is a no-op, but for integers, floating point values, None and boolean values you'll get a nice Unicode representation that can be encoded to UTF-8:
>>> unicode(True).encode('utf8')
'True'

Categories

Resources