Error handling for bad values in JSON loading - python

I have a problem for loading JSON file using json.load.
with open(file) as json_file:
self._metdata = json.load(json_file)
one the rows in the file is bad and gives this error:
Expecting property name enclosed in double quotes: line 515716 column 1 (char 24223047)
What I want it the json.load to ignore this value and keep loading the rest but I could not find a way to do it.
What I finally did is to read line by line and to check for error but its very slow.
Is there a better way to do it?
Thanks.
for file in [self._metadata_file_name, self._pharses_map_file_name]:
with open(file) as json_file:
for line in json_file:
try:
row = json.loads(line)
if row:
if file == self._metadata_file_name:
self._metdata = {**self._metdata, **row}
else:
self._pharses_map = {**self._pharses_map, **row}
except Exception as e:
self._logger.log(message="Error pasring JSON " + line + ", for model: " + self._mode + ", file: " + self._metadata_file_name, error=str(e), metadata={"mode" : self._mode}, logType=self._logger.LOG_TYPE_ERROR)

You can use json.load for loading a file. At line 515716, add double quote wrap the key. Hope to help you

Related

How do I test to see if a line of a .txt exists or not? and then raise and exception?

I've been working on a function for hours and I just can't see the solution since this is my first time working with opening .txt files, etc.
My function will open a .txt file of 50 names, with the first line (a header) being NAMES. And then it will create a list of those names. I need to test the function so if the line 'NAMES' is not in the txt file it will raise an exception. I have been working on the 'NAMES' part for longer than I care to admit and can't see what I am doing wrong. Here is my code:
EOF = ''
def load_names(fName):
global line, names
print(end = f"Opening file {fName} ...")
try:
f = open(fName, 'r')
except:
raise Exception(f"OOPS! File {fName} not found")
print(end = "reading...")
line = f.readline().strip()
while line.strip() != 'NAMES':
line = f.readline().strip()
while line != EOF and line.strip() != 'NAMES':
raise Exception("!! Oops! Missing line 'NAMES' !!" )
names = [] # To collect names from file
line = f.readline().strip() # Read in first name
while line != EOF:
if line =='\n':
print("!! Oops! Blank line not allowed !!")
names.append(line.strip())
line = f.readline()
f.close()
print(end = "closed.\n")
return names
The 'blank line not allowed' works when tested, but the way I have this code written now, even If I open a file that does have the 'NAMES' line in it, it still gives the error "Exception("!! Oops! Missing line 'NAMES' !!" )". I'm not sure how to do it, basically.
The files i am testing this with look like:
With NAMES -
NAMES
Mike
James
Anna
Without NAMES -
Mike
James
Anna
Your function seems much too complex, and the exception handling is wrong. For example, it will replace a "permission denied" exception with a generic Exception with an incorrect message saying the file wasn't found, even though that was not the reason for the error.
Instead, probably
avoid the use of global variables;
don't trap errors you can't meaningfully handle;
don't strip() more than once - save the stripped value so you can use it again;
simply read one line at a time, and check that it passes all your criteria.
def load_names(fName):
with open(fName, 'r') as f:
seen_names = False
names = []
for line in f:
line = line.strip()
if line == 'NAMES':
seen_names = True
elif line == '':
raise Exception("!! Oops! Blank line not allowed !!")
else:
names.append(line)
if not seen_names:
raise Exception("!! Oops! Missing line 'NAMES' !!" )
return names
If you actually want NAMES to be the first line in the file, it's not hard to change the code to require that instead. Maybe then it does make sense to read the first line separately before the loop.
def load_names(fName):
with open(fName, 'r') as f:
seen_names = False
names = []
for line in f:
line = line.strip()
if not seen_names:
if line == 'NAMES':
seen_names = True
else:
raise Exception("!! Oops! Missing line 'NAMES' !!" )
elif line == '':
raise Exception("!! Oops! Blank line not allowed !!")
else:
names.append(line)
return names
Concretely, the bug in your original attempt is that the code continues to read lines until it gets one which doesn't contain NAMES, and then complains.

error Passing a String variable as filename to open a file

i have this problem: i'm tryna list all filenames from a directory and then print them with numbers on the left to let users select the file to use. Numbers are there because they match with the index of the position of filenames in the list. When i select a specific string filename in the list and pass it to
`f = open (filename, "r")
data = json.loads(f.read())`
i get:
Traceback (most recent call last):
File "test.py", line 170, in
data = json.loads(f.read())
AttributeError: 'str' object has no attribute 'loads'
full code:
jsons=glob.glob("*.json")
print(type(jsons))
print(type(jsons[0]))
n=0
if(jsons):
for json in jsons:
print(str(n) + ' - ' + json)
n=n+1
jsonselection=int(input('select your settings file: '))
filename=(" ".join(jsons[jsonselection].split()))
print()
print('your selection: ' + filename)
else:
sys.exit(colored('no json files available.','red'))
f = open (filename, "r")
data = json.loads(f.read())
actually if i pass to the method a random variable defined by me like name='file' it works.. i just can't understand why. Thanks in advance for the help
That would most likely be because of this line of code.
jsons=glob.glob("*.json")
and then you have
for json in jsons:

Trying to use os.path.exists via variables but getting an error

I have a file called serial.dll. The content of this file is another file's name:
a-2ED1-7156.dll
I also have 1 file called a-2ED1-7156.dll in the same directory.
When I try to check if the file exists by reading its name from serial.dll:
f = open('serial.dll', 'r')
serials = f.read()
if os.path.exists(serials):
print("ok")
else:
print("no")
Always results "no".
but:
file = 'a-2ED1-7156.dll'
if os.path.exists(file):
print("ok")
else:
print("no")
Always gives the correct result.
How can I check if the file a-2ED1-7156.dll exists by reading it from the serial.dll file?
Update Try:
f = open('serial.dll', 'r')
lines = f.readline()
for line in lines:
if os.path.exists(line):
print('ok')
else:
print("no")
results error:
no
no
no
no
no
no
no
no
no
no
no
ok
no
no
no
no
Supossing each file is in a separate line, you coud use
lines = f.readlines()
for line in lines:
if os.path.exists(line):
print('ok')
Or print only if all files exist, depending on what you want exactly.
Your problem is that lines in a file might end with the new-line character. File names usually don't have that character... For example, right now you're checking if the file a-2ED1-7156.dll\n exists - which is not. You simply need to strip() the lines before checking them as files:
f = open('serial.dll')
for line in f:
filename = line.strip()
if os.path.exists(filename):
print(f"{filename} exists")
else:
print(f"{filename} doesn't exist")

JSON files parsing error while trying to print certain values using Python (json.decoder.JSONDecodeError: Extra data: line 2 column 1 (char 20))

I am new to Python, and I want to convert a JSON file and print it to the console. When I try to print the whole JSON it is throwing
json.decoder.JSONDecodeError: Extra data: line 2 column 1 (char 20)
My code:
import json
with open('venv/Vt.json', 'r') as json_file:
parsed_json = json.load(json_file)
for idd in parsed_json:
print(idd['t_id'])
My JSON file:
{"index":{"_id":0}}
{"t_id":0,"timestamp":"2016-06-01T09:23:39Z","stat":"571","mod":"M02"}
{"index":{"_id":1}}
{"t_id":0,"timestamp":"2016-06-01T09:23:39Z","stat":"571","mod":"M02"}
While you wait for a better answer, this code (while not great) solves your issue:
with open('venv/Vt.json', 'r') as json_file:
try:
t_ids = [json.loads(line)['t_id'] for line in json_file.readlines()]
print(t_ids)
except Exception:
pass

Python - ValueError: Expecting value: line 1 column 1 (char 0)

This produces and error:
ValueError: Expecting value: line 1 column 1 (char 0)
Here is my code:
...
print("Your phonebook contains the following entries:")
for name, number in phoneBook.items():
print("%s - %s" % (name, number))
while not created:
if not os.path.isfile('phonebook.json'):
with open('phonebook.json', 'wb') as f:
try:
f.write('{}')
except TypeError:
{}
created = True
print('New phonebook created!')
else:
print('Phonebook found!')
created = True
with open('phonebook.json', 'r') as f:
try:
phoneBook_Ori = json.load(f)
phoneBook_Upd = dict(phoneBook_Ori.items() + phoneBook.items())
phoneBook_Ori.write(phoneBook_Upd)
except EOFError:
{}
if EOFError:
with open('phonebook.json', 'w') as f:
json.dump(phoneBook, f)
else:
with open('phonebook.json', 'w') as f:
json.dump(phoneBook_Ori, f)
Has anyone got an idea of how to fix this?
I have also previously asked a question on this code here
I copy pasted your code in the python 2.x interpreter.
I received a ValueError regarding the phonebook.json file. I created a dummy file with:
{'sean':'310'}
My error reads:
ValueError: Expecting property name: line 1 column 2
This was the only way I was able to receive a ValueError.
Therefore, I believe your issue lies in the way the json is written in phonebook.json. Can you post its contents or a subset?
Also, using phoneBook_Ori.write() seems very questionable, as the json module has no method called write(), and the return on json.load(), if used on json objects, is a dictionary, which also cannot write(). You would probably want to use json.dump().
read more at:
https://docs.python.org/2/library/json.html
Anyway, I hope I was helpful.
I was getting this error whilst using json.load(var) with var containing an empty JSON response from a REST API call.
In your case, the JSON response (phonebook.json) must have records. This will fix the error.

Categories

Resources