The JSON in the text file is not in the proper format. The ends of each of the supposed JSON format strings, such as … 91'}}'
and … 68'}}'
are invalid. It should be like this: … 91}}'
.
Here's the corrected file:
Name: Sham
good student
('{"result": {"School name": "abc", "roll no": 2, "Class": "7B", "Marks": '
'310.55, "class_average_percentage": 81.523, "percentage": 91}}')
Name: Ram
need to improve
('{"result": {"School name": "abc", "roll no": 3, "Class": "8A", "Marks": '
'250.89, "class_average_percentage": 86.23, "percentage": 68}}')
Name: Roy
average student
('{"result": {"School name": "abc", "roll no": 9, "Class": "7B", "Marks": '
'298.45, "class_average_percentage": 81.523, "percentage": 73}}')
I was able to parse the fixed version of your Result.txt
shown above via something called a FSM (Finite-State-Machine) because they're able to parse patterns such as what's in the contents of this file. In a nutshell, they're are always in one of a finite number of states and change or transition from one state to another based on the input they're fed iteratively (such as lines of a text file).
To handle the JSON data, the code gathers the lines together comprising the JSON string which appears to be in Python literal string format, then it joins them all and applies ast.literal_eval()
to them to obtain the string value. It then uses json.loads()
to convert that into a Python dictionary, and then converts a nested dictionary in that intermediate result back into a JSON string using json.dumps()
which it adds the student_info
dictionary being built.
While at that point it would be possible to use the student's name to create a variable and assign the JSON string to it, that is generally considered a poor practice — so instead, the code creates a dictionary named student_info
to hold the results. The keys of the dictionary are the student's name and value associated with each on it the JSON format string in the file.
from ast import literal_eval
import json
filepath = './Result.txt'
student_info = {}
with open(filepath) as file:
state = 0
while True:
try:
line = next(file)
except StopIteration: # End-Of-File
break
if not (line := line.strip()): # Skip blank lines.
continue
if state == 0:
if line.startswith('Name:'): # First line of student data?
name = line.split()[1]
json_lines = []
state = 1
elif state == 1:
if line.startswith('('): # First JSON line?
json_lines.append(line)
state = 2
elif state == 2:
json_lines.append(line)
if line.endswith(')'): # Last JSON line?
json_str = literal_eval(''.join(json_lines))
result_dict = json.loads(json_str)
as_json = json.dumps(result_dict['result'])
student_info[name] = f'({repr(as_json)})'
state = 0
for student, json_str in student_info.items():
print(f'{student}: {json_str}')
Printed results:
Sham: ('{"School name": "abc", "roll no": 2, "Class": "7B", "Marks": 310.55, "class_average_percentage": 81.523, "percentage": 91}')
Ram: ('{"School name": "abc", "roll no": 3, "Class": "8A", "Marks": 250.89, "class_average_percentage": 86.23, "percentage": 68}')
Roy: ('{"School name": "abc", "roll no": 9, "Class": "7B", "Marks": 298.45, "class_average_percentage": 81.523, "percentage": 73}')