I'm working on an address book in python, and I'm trying to save the data (name, town & address) to a json file.
The problem's that when it saves to the json file, it creates a new object in the json file
example -
{"Object1": {"Town": "town", "Address": "address"}}
{"Object2": {"Town": "town", "Address": "address"}}
Because of that layout, I get this error whenever I try to do anything with it
Error -
ValueError: Extra data: line 2 column 1 - line 2 column 55 (char 55 - 109)
How can I make my json file layout something like this
Example -
{"Object1": {"Town": "town", "Address": "address", "Object2": {"Town": "town", "Address": "address"}}
Here's my code -
import json
class Object:
name = "Name"
address = "Address"
town = "Town"
def return_info(self):
dictionary = {self.name: {"Address": self.address, "Town": self.town}}
return dictionary
def __init__(self, entered_name, entered_town, entered_address):
self.name = entered_name
self.town = entered_town
self.address = entered_address
def update(file):
with open("data.json", "a") as outfile:
json.dump(file, outfile)
new_object = Object("name", "town", "address")
update(new_object.return_info())
You can just maintain all addresses in a dict and then dump into a json file.
addressmap = {
"Object1": {"town": "town", "address": "address"},
"Object2": {"town": "town", "address": "address"}
}
with open("addresses.json", "w") as f:
json.dump(addressmap, f, indent=4)
Your example of a desired object means having Object2 inside Object1, while it seems to me what you'd like is a list of your objects:
import json
dictlist = [{"Object1": {"Town": "town", "Address": "address"}},
{"Object2": {"Town": "town", "Address": "address"}}]
with open("output.json", "w") as outfile:
json.dump(dictlist, outfile)
Related
I'm very new to programming so excuse any terrible explanations. Basically I have 1000 json files all that need to have the same text added to the end. Here is an example:
This is what it looks like now:
{"properties": {
"files": [
{
"uri": "image.png",
"type": "image/png"
}
],
"category": "image",
"creators": [
{
"address": "wallet address",
"share": 100
}
]
}
}
Which I want to look like this:
{"properties": {
"files": [
{
"uri": "image.png",
"type": "image/png"
}
],
"category": "image",
"creators": [
{
"address": "wallet address",
"share": 100
}
]
},
"collection": {"name": "collection name"}
}
I've tried my best with append and update but it always tells me there is no attribute to append. I also don't really know what I'm doing.
This will be embarrassing but here is what I tried and failed.
import json
entry= {"collection": {"name": "collection name"}}
for i in range((5)):
a_file = open("./testjsons/" + str(i) + ".json","r")
json_obj = json.load(a_file)
print(json_obj)
json_obj["properties"].append(entry)
a_file = open(str(i) + ".json","w")
json.dump(json_obj,a_file,indent=4)
a_file.close()
json.dump(a_file, f)
Error code: json_obj["properties"].append(entry)
AttributeError: 'dict' object has no attribute 'append'
you don't use append() to add to a dictionary. You can either assign to the key to add a single entry, or use .update() to merge dictionaries.
import json
entry= {"collection": {"name": "collection name"}}
for i in range((5)):
with open("./testjsons/" + str(i) + ".json","r") as a_file:
a_file = open("./testjsons/" + str(i) + ".json","r")
json_obj = json.load(a_file)
print(json_obj)
json_obj.update(entry)
with open(str(i) + ".json","w") as a_file:
json.dump(json_obj,a_file,indent=4)
JSON, like XML, is a specialized data format. You should always parse the data and work with it as JSON where possible. This is different from a plain text file where you would 'add to the end' or 'append' text.
There are a number of json parsing libraries in Python, but you'll probably want to use the json encoder that is built in to the standard Python library. For a file, myfile.json, you can:
import json
with open('myfile.json`, 'r') as f:
myfile = json.load(f) # read the file into a Python dict
myfile["collection"] = {"name": "collection name"} # here you're adding the "collection" field to the end of the Python dict
# If you want to add "collection" inside "properties", you'd do something like
#. myfile["properties"]["collection"] = {"name": "collection name"}
with open('myfile.json', 'w') as f:
json.dump(myfile, f) # save the modified dict into the json file
[
{
"name": "name one",
"id": 1
},
{
"name": "name two",
"id": 2
}
]
I want to append object to the list in .json file. how do i do?
You could read the existing json content update it and rewrite the updated list.
import json
with open("myfile.json", "r+") as f:
my_file = f.read() # read the current content
my_list = json.loads(my_file) # convert from json object to dictionary type
dict_obj = {
"name": "name three",
"id": 3
}
my_list.append(dict_obj)
f.seek(0) # sets point at the beginning of the file
f.truncate() # Clear previous content
print(f" going to rewrite {my_list}")
f.write(json.dumps(my_list)) # Write updated version file
I'm not entirely sure of what you are asking but perhaps the code below will help:
const myList = [
{
"name": "name one",
"id": 1
},
{
"name": "name two",
"id": 2
}
]
const myNewItem = {
"name": "name three",
"id": 3
}
const addItemIfDifferentId = (list, newItem) => [...list, !list.map(({id}) =>id).includes(newItem.id) ? {...newItem} : {} ]
const newList = addItemIfDifferentId(myList, myNewItem)
newList
Maybe this will help you:
import json
# When loading a .json files it will be a string:
with open('data.json') as json_file:
x = json.load(json_file) //{"key1":"123", "key2":"456", "key3":"789"}
# python object to be appended
y = {"key4": "101112"}
# Load the json string to be an object type:
z = json.loads(x)
# appending the data
z.update(y)
# the result is a JSON string:
print(json.dumps(z))
with open('data.json', 'w') as outfile:
json.dump(z, outfile)
{
"Basketball": {
"first_name": "Michael",
"last_name": "Jordan"
},
"Football": {
"first_name": "Leo",
"last_name": "Messi"
},
"Football2": {
"first_name": "Cristiano",
"last_name": "Ronaldo"
}
}
This is my json file. I want to delete "Football2" out of this json file. It should work no matter what the value of "Football2" is.
So it should look like this after my code is executed:
{
"Basketball": {
"first_name": "Michael",
"last_name": "Jordan"
},
"Football": {
"first_name": "Leo",
"last_name": "Messi"
}
}
This is my code.
def delete_profile():
delete_profile = input('Which one would you like to delete? ')
with open(os.path.join('recources\datastorage\profiles.json')) as data_file:
data = json.load(data_file)
for element in data:
print(element)
if delete_profile in element:
del(element[delete_profile])
with open('data.json', 'w') as data_file:
json.dump(data, data_file)
But it gives this error: TypeError: 'str' object does not support item deletion
What am I doing wrong and what is the correct way to do this?
Youre looping over the items in your JSON dictionary unnecessarily when you just want to delete the "top" level items:
def delete_profile():
delete_profile = input('Which one would you like to delete? ')
with open(os.path.join('recources\datastorage\profiles.json')) as data_file:
data = json.load(data_file)
# No need to loop, just check if the profile is in the JSON dictionary since your 'profiles' are top-level objects
if (delete_profile in data):
# Delete the profile from the data dictionary, not from the elements of the dictionary
del(data[delete_profile])
# Maybe add an else to handle if the requested profile is not in the JSON?
with open('data.json', 'w') as data_file:
json.dump(data, data_file)
I am having trouble with converting a dictionary to a string in python. I am trying to extract the information from one of my variables but cannot seem to remove the square brackets surrounding the information
for line in str(object):
if line.startswith ('['):
new_object = object.replace('[', '')
Is there a way to remove the square brackets or do I have to find another way of taking the information out of the dictionary?
Edit:
in more detail what i am trying to do here is the following
import requests
city = 'dublin'
country = 'ireland'
info = requests.get('http://api.openweathermap.org/data/2.5/weather?q='+city +','+ country +'&mode=json')
weather = info.json()['weather']
fh = open('/home/Ricky92d3/city.txt', 'w')
fh.write(str(weather))
fh.close()
fl = open('/home/Ricky92d3/city.txt')
Object = fl.read()
fl.close()
for line in str(Object):
if line.startswith ('['):
new_Object = Object.replace('[', '')
if line.startswith ('{'):
new_Object = Object.replace('{u', '')
print new_Object
i hope this makes what i am trying to do a little more clear
The object returned by info.json() is a Python dictionary, so you can access its contents using normal Python syntax. I admit that it can get a little bit tricky, since JSON dictionaries often contain other dictionaries and lists, but it's generally not too hard to figure out what's what if you print the JSON object out in a nicely formatted way. The easiest way to do that is by using the dumps() function in the standard Python json module.
The code below retrieves the JSON data into a dict called data.
It then prints the 'description' string from the list in the 'weather' item of data.
It then saves all the data (not just the 'weather' item) as an ASCII-encoded JSON file.
It then reads the JSON data back in again to a new dict called newdata, and pretty-prints it.
Finally, it prints the weather description again, to verify that we got back what we saw earlier. :)
import requests, json
#The base URL of the weather service
endpoint = 'http://api.openweathermap.org/data/2.5/weather'
#Filename for saving JSON data to
fname = 'data.json'
city = 'dublin'
country = 'ireland'
params = {
'q': '%s,%s' % (city, country),
'mode': 'json',
}
#Fetch the info
info = requests.get(endpoint, params=params)
data = info.json()
#print json.dumps(data, indent=4)
#Extract the value of 'description' from the list in 'weather'
print '\ndescription: %s\n' % data['weather'][0]['description']
#Save data
with open(fname, 'w') as f:
json.dump(data, f, indent=4)
#Reload data
with open(fname, 'r') as f:
newdata = json.load(f)
#Show all the data we just read in
print json.dumps(newdata, indent=4)
print '\ndescription: %s\n' % data['weather'][0]['description']
output
description: light intensity shower rain
{
"clouds": {
"all": 75
},
"name": "Dublin",
"visibility": 10000,
"sys": {
"country": "IE",
"sunset": 1438374108,
"message": 0.0118,
"type": 1,
"id": 5237,
"sunrise": 1438317600
},
"weather": [
{
"description": "light intensity shower rain",
"main": "Rain",
"id": 520,
"icon": "09d"
}
],
"coord": {
"lat": 53.340000000000003,
"lon": -6.2699999999999996
},
"base": "stations",
"dt": 1438347600,
"main": {
"pressure": 1014,
"humidity": 62,
"temp_max": 288.14999999999998,
"temp": 288.14999999999998,
"temp_min": 288.14999999999998
},
"id": 2964574,
"wind": {
"speed": 8.1999999999999993,
"deg": 210
},
"cod": 200
}
description: light intensity shower rain
I'm not quite sure what you're trying to do here (without seeing your dictionary) but if you have a string like x = "[myString]" you can just do the following:
x = x.replace("[", "").replace("]", "")
If this isn't working, there is a high chance you're actually getting a list returned. Though if that was the case you should see an error like this:
>>> x = [1,2,3]
>>> x.replace("[", "")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute 'replace'
Edit 1:
I think there's a misunderstanding of what you're getting back here. If you're just looking for a csv output file with the weather from your api try this:
import requests
import csv
city = 'dublin'
country = 'ireland'
info = requests.get('http://api.openweathermap.org/data/2.5/weather?q='+city +','+ country +'&mode=json')
weather = info.json()['weather']
weather_fieldnames = ["id", "main", "description", "icon"]
with open('city.txt', 'w') as f:
csvwriter = csv.DictWriter(f, fieldnames=weather_fieldnames)
for w in weather:
csvwriter.writerow(w)
This works by looping through the list of items you're getting and using a csv.DictWriter to write it as a row in the csv file.
Bonus
Don't call your dictionary object - It's a reserved word for the core language.
I have here a set of json objects.
[
{
"group": "GroupName1",
"name": "Name1",
"nick": "Nick1",
"host": "Hostname1",
"user": "user1",
"sshport": "22",
"httpport": "80"
},
{
"group": "GroupName2",
"name": "Name2",
"nick": "Nick2",
"host": "hostname2",
"user": "user2",
"sshport": "22",
"httpport": "80"
}
]
I have a CLI script taking raw_input and building a new dict object containing the new object parameters as such:
def main():
# CLI Input
group_in = raw_input("Group: ")
name_in = raw_input("Name: ")
nick_in = raw_input("Nick: ")
host_in = raw_input("Host: ")
user_in = raw_input("User: ")
sshport_in = raw_input("SSH Port: ")
httpport_in = raw_input("HTTP Port: ")
# New server to add
jdict = {
"group": group_in,
"name": name_in,
"nick": nick_in,
"host": host_in,
"user": user_in,
"sshport": sshport_in,
"httpport": httpport_in
}
Assuming json file containing the aforementioned json objects formatted as such is loaded as:
with open(JSON_PATH, mode='r') as rf:
jf = json.load(rf)
I know how to do this by hacking the file using readlines/writelines, but how would I add jdict in at the end of jf pythonically so I can just write the file back with the complete new set of objects formatted in the same way?
jf is now just a Python list, so you can append the new dictionary to your list:
jf.append(jdict)
then write out the whole object back to your file, replacing the old JSON string:
with open(JSON_PATH, mode='w') as wf:
json.dump(jf, wf)