Writing list of objects to JSON file - python

As part of my homework I have to make a JSON file with class objects in it. I could do it, but the result is not that i expected.
import json
stList = []
class Student(object):
neptun_code = ""
result = 0
mark = 0
def make_student(neptun_code, result, mark):
student = Student()
student.neptun_code = neptun_code
student.result = result
student.mark = mark
stList.append(student)
def create_json():
json_string = json.dumps([ob.__dict__ for ob in stList])
with open("./data/student.txt", "w") as file:
json.dump(json_string, file)
Sample inputs for make_student : test_code, test_result, test_mark
Here is the output in student.txt:
"[{\"neptun_code\": \"test_code\", \"result\": \"test_result\", \"mark\": \"test_mark\"}]"
there are plenty of unwanted characters in it. I would like to have something like this:
[{"neptun_code": "test_code", "result": "test_result", "mark": "test_mark"}]
Can anyone explain how to do this?

You should use either dumps, or dump. Not both.
dump (my preference):
def create_json():
with open("./data/student.txt", "w") as file:
json.dump([ob.__dict__ for ob in stList], file)
OR dumps:
def create_json():
json_string = json.dumps([ob.__dict__ for ob in stList])
with open("./data/student.txt", "w") as file:
file.write(json_string)
As a side note, in the future you'll want to watch out for scoping as you're using the global object stList.

You are encoding your dictionary to JSON string twice. First you do this here:
json_string = json.dumps([ob.__dict__ for ob in stList])
and then once again, here:
json.dump(json_string, file)
Alter this line with file.write(json_string)

Related

how do I add a string to a json value in python 3

So I'm trying to setup json so i can store data in-between user sessions I like a name but i don't know how to add or change a specific value in an external json file like for example {"name": ""} how do i fill that "" for the json file using python?
I have already tried to use dumps and all the tutorials use dumps
the json in another file
{
"human_name": "",
"oracle_name": "",
"human_age": "",
"human_gender": "",
"oracle_gender": ""
}
the python
import json
with open('data.json', '+') as filedata:
data = filedata.read()
used_data = json.loads(data)
if str(used_data(['human_name'])) == "":
print("what is your name")
name = input()
json.dumps(name)
if str(used_data(['oracle_name'])) == "":
print("what is my name")
oracle_name = input()
json.dumps(oracle_name)
print(str(['human_name']))
The expected result is when I print the data it displays input, but when i run it it goes
File "rember.py", line 3, in
with open('data.json', '+') as filedata: ValueError: Must have exactly one of create/read/write/append mode and at most one plus
Try this code.
json.loads loads the entire json string as a python dict object. The values in a dict are changed/added using dict[key] = value. You can't call a dict object to change its value.
The json.dumps method serializes an object to a JSON formatted str. Which you can then write into the same file or a different file based on your requirement.
import json
with open('data.json', 'r') as filedata:
data = filedata.read()
used_data = json.loads(data)
if used_data['human_name'] == "":
print("what is your name")
name = input()
used_data['human_name'] = name
if used_data['oracle_name'] == "":
print("what is my name")
oracle_name = input()
used_data['oracle_name'] = oracle_name
print(used_data)
with open('data.json', 'w') as filewrite:
filewrite.write(json.dumps(used_data, indent=4))
Basically what you need to do is load json file as dictionary, add value, and save it.
import json
with open('./data.json', 'r') as f:
d = json.load(f)
d['human_name'] = 'steve'
d['oracle_name'] = 'maria'
with open('./data.json', 'w') as f:
json.dump(d, f, indent=4)

How to input a JSON file an print a line

Write a program that inputs a JSON file (format just like
example1.json) and prints out the value of the title field.
import json
# TODO: Read your json file here and return the contents
def read_json(filename):
dt = {}
# read the file and store the contents in the variable 'dt'
with open(filename,"r") as fh:
dt = json.load(fh)
###fh = open(filename, "r")
###dt = json.load(fh)
return dt
# TODO: Pass the json file here and print the value of title field. Remove the `pass` statement
def print_title(dt):
print filename["title"]
# TODO: Input a file from the user
filename = raw_input("Enter the JSON file: ")
# The function calls are already done for you
r = read_json(filename)
print_title(r)
Hi, I'm new with Python and I'm not sure what I am doing wrong. I keep getting the following message:
enter image description here
Your'e almost there, you just confused with the parameter name.
Change this:
def print_title(dt):
print filename["title"]
To:
def print_title(dt):
print dt["title"]

How to store a html file in a variable as a string in python

I have html file and I want to store the contents of that file in a variable as a string value. I have tried this but it returns a blank string. How can I do this?
def myfunc():
str = ""
with open("/home/suman/Alert_logo_report.html") as report_file:
raw_html = report_file.readlines()
str = ''.join(raw_html)
return str
Strange, I don't see that behavior:
def get_content(path):
with open(path) as f:
raw_lines = f.readlines()
content = ''.join(raw_lines)
return content
gives me the HTML content.
On the other hand:
-you're overwriting str that is a basic python function transforming something in a string. I cannot see this ending well (meaning: I've done it in the past, it wasn't pretty)
-there is not need to declare a variable, this is python
-I don't understand why reading lines, then joining them without doing anything.
The way I see it, this would be better:
def get_content(path):
with open(path) as f:
raw = f.read()
return raw
Use """string_literal""" instead of "string_literal" or 'string_literal'. """string_literal""" is for multi line strings. This will work.
def myfunc():
str = """"""
with open("employees.html") as report_file:
raw_html = report_file.readlines()
str = """""".join(raw_html)
return str
Try this
f = open("0101.html", "r")
str1 = f.readlines()
print(str1)
f.close()

Python, write json / dictionary objects to a file iteratively (one at a time)

I have a large for loop in which I create json objects and I would like to be able to stream write the object in each iteration to a file. I would like to be able to use the file later in a similar fashion later (read objects one at a time).
My json objects contain newlines and I can't just dump each object as a line in a file.
How can I achieve this?
To make it more concrete, consider the following:
for _id in collection:
dict_obj = build_dict(_id) # build a dictionary object
with open('file.json', 'a') as f:
stream_dump(dict_obj, f)
stream_dump is the function that I want.
Note that I don't want to create a large list and dump the whole list using something like json.dump(obj, file). I want to be able to append the object to the file in each iteration.
Thanks.
You need to work with a subclass of JSONEncoder and then proxy the build_dict function
from __future__ import (absolute_import, division, print_function,)
# unicode_literals)
import collections
import json
mycollection = [1, 2, 3, 4]
def build_dict(_id):
d = dict()
d['my_' + str(_id)] = _id
return d
class SeqProxy(collections.Sequence):
def __init__(self, func, coll, *args, **kwargs):
super(SeqProxy, *args, **kwargs)
self.func = func
self.coll = coll
def __len__(self):
return len(self.coll)
def __getitem__(self, key):
return self.func(self.coll[key])
class JsonEncoderProxy(json.JSONEncoder):
def default(self, o):
try:
iterable = iter(o)
except TypeError:
pass
else:
return list(iterable)
# Let the base class default method raise the TypeError
return json.JSONEncoder.default(self, o)
jsonencoder = JsonEncoderProxy()
collproxy = SeqProxy(build_dict, mycollection)
for chunk in jsonencoder.iterencode(collproxy):
print(chunk)
Ouput:
[
{
"my_1"
:
1
}
,
{
"my_2"
:
2
}
,
{
"my_3"
:
3
}
,
{
"my_4"
:
4
}
]
To read it back chunk by chunk you need to use JSONDecoder and pass a callable as object_hook. This hook will be called with each new decoded object (each dict in your list) when you call JSONDecoder.decode(json_string)
Since you are generating the files yourself, you can simply write out one JSON object per line:
for _id in collection:
dict_obj = build_dict(_id) # build a dictionary object
with open('file.json', 'a') as f:
f.write(json.dumps(dict_obj))
f.write('\n')
And then read them in by iterating over lines:
with open('file.json', 'r') as f:
for line in f:
dict_obj = json.loads(line)
This isn't a great general solution, but it's a simple one if you are both the generator and consumer.
Simplest solution:
Remove all whitespace characters from your json document:
import string
def remove_whitespaces(txt):
""" We shall remove all whitespaces"""
for chr in string.whitespace:
txt = txt.replace(chr)
Obviously you could also json.dumps(json.loads(json_txt)) (BTW this also verify that the text is a valid json).
Now you could write you documents to a file one line each.
Second solution:
Create an [AnyStr]Io stream, write in the Io a valid document, (your documents being part of an object or list) and then write the io in a file (or upload it to the cloud).

python implementation of 'readAsDataURL

i'm having some troubles to get the URI from a certain file, like .mp4/.ogg/etc..
The thing is that i need to do it in python, where the webserver is running.
Initially, i proceed like this:
def __parse64(self, path_file):
string_file = open(path_file, 'r').readlines()
new_string_file = ''
for line in string_file:
striped_line = line.strip()
separated_lines = striped_line.split('\n')
new_line = ''
for l in separated_lines:
new_line += l
new_string_file += new_line
self.encoded_string_file = b64.b64encode(new_string_file)
But this way, doesn't give what i need, if you compare the result with given here.
What a i need is a way to implement the function readAsDataURL() from FileReader class (see the code of the link above), in python.
UPDATE:
The solution given by #SeanVieira, returns a valid data field for the URI.
def __parse64(self, path_file):
file_data = open(path_file, 'rb').read(-1)
self.encoded_string_file = b64.b64encode(file_data)
Now how can i complete the URI, with the previous fields?
Like this.
For example: data:video/mp4;base64,data
Thanks!
The problem is that you are treating binary-encoded data as text data, which is breaking your code.
Try:
def __parse64(self, path_file):
file_data = open(path_file, 'rb').read(-1)
#This slurps the whole file as binary.
self.encoded_string_file = b64.b64encode(file_data)
The #SeanVieria answer will not work if the file is very large (more than 7mb)
This function will work for all cases (tested on Python version 3.4):
def __parse64(self, path_file):
data = bytearray()
with open(path_file, "rb") as f:
b = f.read(1)
while b != b"":
data.append(int.from_bytes(b, byteorder='big'))
b = f.read(1)
self.encoded_string_file = base64.b64encode(data)

Categories

Resources