Loading a file as a JSON in python? - python

I'm quite new to python and im trying to get a JSON file to be created and then loaded and then organised. But I keep getting a weird error.
This is my code to write the file:
def save(): # save to file
with open(class_name, 'a') as f:
data = [name, score]
json.dump(data, f)
This is my code to load the file:
with open(class_name, 'r') as f:
data2 = json.load(f)
This is my code to organise the file:
with open(class_name, 'r') as f:
data2 = json.load(f)
Alpha = sorted(data, key=str.lower)
print(Alpha)
And this is my error:
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
viewscores()
File "C:\Users\Danny\Desktop\Task123.py", line 60, in viewscores
data2 = json.load(f)
File "C:\Python34\lib\json\__init__.py", line 268, in load
parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw)
File "C:\Python34\lib\json\__init__.py", line 318, in loads
return _default_decoder.decode(s)
File "C:\Python34\lib\json\decoder.py", line 346, in decode
raise ValueError(errmsg("Extra data", s, end, len(s)))
ValueError: Extra data: line 1 column 13 - line 1 column 153 (char 12 - 152)

You are appending data to your file, creating multiple JSON documents in that file. The json.load() command on the other hand can only load one JSON document from a file, and is now complaining you have more data after the JSON document.
Either adjust your code to load those documents separately (insert newlines after each entry you append, and load the JSON documents line by line, or replace everything in the file with a new JSON object.
Using newlines as separators, then loading all the entries separately would look like:
def save(): # save to file
with open(class_name, 'a') as f:
data = [name, score]
json.dump(data, f)
f.write('\n')
and loading would be:
with open(class_name, 'r') as f:
scores = []
for line in f:
entry = json.loads(line)
scores.append(entry)
after which you could sort those entries if you so wish.

Related

Json file cant be edited

I want to append the brightness 0 to all lamps in list to a empty json file.
def first_start(lamps:list):
for lamp in lamps:
dict = {"light": {lamp: {"brightness": 0}}}
with open("data.json", "r") as file:
data = json.load(file)
data.update(dict)
print(dict)
with open("data.json", 'w') as file:
json.dump(data, file)
Everytime I run this code, I get this error:
Traceback (most recent call last):
File "C:\Users\brend\PycharmProjects\Hue_Control\main.py", line 27, in <module>
first_start(lamps)
File "C:\Users\brend\PycharmProjects\Hue_Control\main.py", line 16, in first_start
data = json.load(file)
File "C:\Users\brend\AppData\Local\Programs\Python\Python39\lib\json\__init__.py", line 293, in load
return loads(fp.read(),
File "C:\Users\brend\AppData\Local\Programs\Python\Python39\lib\json\__init__.py", line 346, in loads
return _default_decoder.decode(s)
File "C:\Users\brend\AppData\Local\Programs\Python\Python39\lib\json\decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Users\brend\AppData\Local\Programs\Python\Python39\lib\json\decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
Could somebody please help me, what im doing wrong?
Thank you :)
There is no such thing as an empty json file. If you have an empty file, then its not a json file.
You could ignore all the errors and assume that the file should contain "{}" and carry on:
def first_start(lamps:list):
for lamp in lamps:
upd = {"light": {lamp: {"brightness": 0}}}
data = {} # Empty dict just in case
try:
with open("data.json", "r") as file:
data = json.load(file)
except Exception:
print('Ignore errors with data.json')
data.update(upd)
with open("data.json", 'w') as file:
json.dump(data, file)

Cannot load a JSON file I just created (json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0))

I'm trying to work with json files, but I'm unable to load the file I just saved.
time_vals = { "seconds": time_spent, "day": amnt}
json_o = json.dumps(time_vals, indent = 4)
with open(os.path.join(os.getcwd(), fname + ".json",), 'a+') as f:
loaded = json.loads(f.read()) <- error
f.write(json_o)
I'm not sure what I'm doing wrong. I tried json.loads(f.read().decode('UTF-8')) and json.load(f) and they both give me errors as well.
Edit:
The purpose of this code is to store time spent on something as a json, and if the time exceeds a certain amount add something else (that's why I'm trying to load the file, to attempt to get the int values stored)
Traceback when using json.load(f):
Traceback (most recent call last):
File "C:\Users\julkt\PycharmProjects\pythonProject\venv\lib\site-packages\flask\app.py", line 2070, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\julkt\PycharmProjects\pythonProject\venv\lib\site-packages\flask\app.py", line 1515, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\julkt\PycharmProjects\pythonProject\venv\lib\site-packages\flask\app.py", line 1513, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\julkt\PycharmProjects\pythonProject\venv\lib\site-packages\flask\app.py", line 1499, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "C:/Users/julkt/Documents/Python_projectaaaaaaaaaaaaas/GUI project/guiproject.py", line 346, in send_url
loaded = json.load(f)
File "C:\Users\julkt\AppData\Local\Programs\Python\Python38\lib\json\__init__.py", line 293, in load
return loads(fp.read(),
File "C:\Users\julkt\AppData\Local\Programs\Python\Python38\lib\json\__init__.py", line 357, in loads
return _default_decoder.decode(s)
File "C:\Users\julkt\AppData\Local\Programs\Python\Python38\lib\json\decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Users\julkt\AppData\Local\Programs\Python\Python38\lib\json\decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
192.168.1.162 - - [16/Sep/2021 18:01:25] "POST /send_url HTTP/1.1" 500 -
When you open a file "a+" (append plus read), the file pointer is set at the end of file, ready for the next write to append data. when you read, its already at EOF so you get the empty string "". Its the same as if you had witten
json.loads("")
Its hard to manage a file for writing and reading, especially with python where an intermediate encoder/decoder for bytes to str translation may be caching data. There are other details to consider such as flushing data to make sure its really available for a read.
Better to segment your code to reading bits and writing bits, and close the file in between. To get the same sequence you've shown, you could
import json
time_vals = { "seconds": 20, "day": 44}
# load records
try:
with open("test.json") as f:
records = [json.loads(line) for line in f]
print("records", records)
except OSError:
print("no records")
# append new record
with open("test.json", "a") as f:
print(json.dumps(time_vals), file=f) # print record with newline
Running multiple times I get
td:~/tmp/e$ python3 test.py
records [{'seconds': 20, 'day': 44}]
td:~/tmp/e$ python3 test.py
records [{'seconds': 20, 'day': 44}, {'seconds': 20, 'day': 44}]
td:~/tmp/e$ python3 test.py
records [{'seconds': 20, 'day': 44}, {'seconds': 20, 'day': 44}, {'seconds': 20, 'day': 44}]
Have you tried to open the JSON with something like jsonvier to see if the JSON is properly constructed? Could be some indentation problems or similar maybe
Use json.load() for file instead of json.loads() used for strings.
From the documentation:
json.load(): Deserialize fp (a .read()-supporting text file or binary file containing a JSON document) to a Python object using this conversion table.
json.loads(): Deserialize s (a str, bytes or bytearray instance containing a JSON document) to a Python object using this conversion table.
You can split your actions in two way. First retrieve the JSON content from your file:
with open(os.path.join(os.getcwd(), fname + ".json")) as f:
loaded = json.load(f)
# do your stuff with the loaded obj
Then write your new JSON to your file with json.dump():
with open(os.path.join(os.getcwd(), fname + ".json"), 'w') as outfile:
json.dump(loaded, outfile)
When you open the file with mode "a+", you can read or write but the main idea is "append": the file pointer is placed at the end of the file, so there is nothing to read there!
Keep it simple, open the file separately for reading and writing, and you should be all right.
with open(fname + ".json", 'r') as f:
loaded = json.load(f)
...
with open(fname + ".json", 'w') as f:
...

Json Decode Error While loading multiple files from directory

import json
import pandas as pd
import collections
import os
path = '/home/vinay/hdfs/kafka-logs/event_tablenames.txt'
file_read = '/home/vinay/hdfs/kafka-logs/hdfs_events/'
table_file = '/home/hdfs/vinay/kafka-logs/events_tables/'
con_json = '/home/vinay/hdfs/kafka-logs/json_to_txt/'
os.chdir(file_read)
files=os.listdir('.')
for file in files:
line = file.split('.')[0]
with open(file ,'r') as f:
print (json.load(f))
data = json.load(f)
key = data[line]
od = collections.OrderedDict(sorted(key.items()))
df = pd.DataFrame(list(od.items()), columns=['col_name', 'type'])
df['col_name'].to_csv(con_json + line + '.txt',sep='\t', index=False, header=False)
Below is a full traceback:
Traceback (most recent call last):
File "events_match_hdfs.py", line 29, in <module>
data = json.load(f)
File "/home/vinay/anaconda3/lib/python3.5/json/__init__.py", line 268, in load
parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw)
File "/home/vinay/anaconda3/lib/python3.5/json/__init__.py", line 319, in loads
return _default_decoder.decode(s)
File "/home/vinay/anaconda3/lib/python3.5/json/decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/home/vinay/anaconda3/lib/python3.5/json/decoder.py", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
You didn't show the full traceback from the error in your question, so this is a just a guess.
I think the problem is because you're trying to do json.load(f) twice on the same file. The first one consumes the entire file, so the second one fail. Try changing the first couple of lines after opening the file to this:
with open(file ,'r') as f:
data = json.load(f)
print(data)
Json filename was not proper,and the size was zero.Due to that it was
throwing error.
Thanks all for your inputs.

How do I give a JSON string object an attribute to read?

I'm trying to use JSON to select objects from a list, then delete those objects once they've been selected. I keep running into errors telling me
AttributeError: 'str' object has no attribute 'read'
path_album_list = 'C:\\Users\\steve\\AppData\\Local\\Programs\\Python\\Python36\\albums.json'
albums = json.load(path_album_list)
album = random.choice(albums)
print ('Today\'s soundtrack is "%s."' % album)
albums.remove(album)
json.dump(albums, path_album_list)
I also tried using json.loads, but then I got even more errors:
Traceback (most recent call last):
File "C:\Users\steve\AppData\Local\Programs\Python\Python36\randomizer.py", line 20, in <module>
albums = json.loads(path_album_list)
File "C:\Users\steve\AppData\Local\Programs\Python\Python36\lib\json\__init__.py", line 354, in loads
return _default_decoder.decode(s)
File "C:\Users\steve\AppData\Local\Programs\Python\Python36\lib\json\decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Users\steve\AppData\Local\Programs\Python\Python36\lib\json\decoder.py", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)*
json.load takes a file object, not a string. So you need to do this:
path_album_list = 'C:\\Users\\steve\\AppData\\Local\\Programs\\Python\\Python36\\albums.json'
jsonfile = open(path_album_list, "r")
albums = json.load(jsonfile)
jsonfile.close()
# ...
jsonfile = open(path_album_list, "w")
json.dump(albums, jsonfile)
jsonfile.close()
Or, you can use with statements, but the above is probably easier to understand.
path_album_list = 'C:\\Users\\steve\\AppData\\Local\\Programs\\Python\\Python36\\albums.json'
with open(path_album_list, "r") as jsonfile:
albums = json.load(jsonfile)
# ...
with open(path_album_list, "w") as jsonfile:
json.dump(albums, jsonfile)
The reason you need to open the files is that json interacts with files, not with strings of the file path.

ValueError: Extra data: Importing multiple JSON frame from JSON file in python

I am trying to import multiple JSON frames stored in JSON file to python.
My code is:
import json
import array
with open("J1.json") as J:
j_Data = json.load(J)
print j_Data
Error :
Traceback (most recent call last):
File "/home/abhi/Desktop/CSS HTML/Python Mongo/JSONtoMongoDB.py", line 9, in <module>
j_Data = json.load(J)
File "/usr/lib/python2.7/json/__init__.py", line 290, in load
**kw)
File "/usr/lib/python2.7/json/__init__.py", line 338, in loads
return _default_decoder.decode(s)
File "/usr/lib/python2.7/json/decoder.py", line 369, in decode
raise ValueError(errmsg("Extra data", s, end, len(s)))
ValueError: Extra data: line 1 column 1113 - line 1 column 2225 (char 1112 - 2224)
My JSON file data is as follows:
If you can make array of your JSON frames in JSON file:
[{"yphthd": "123.32"} , {"yphthd": "123.32"}, ... {"yphthd": "123.32"}]
and then load it:
with open("J1.json") as J:
j_Data = json.load(J)
print j_Data

Categories