2
\$\begingroup\$

I am new to python so I decided to write a script that parses a json array and writes data in a file.

I wrote the code that does that but I think it can be done way better, So I was hoping to get feedback on how this code can be enhanced and more inline with python best practices.

from urllib2 import urlopen
import json

def get_json(url):
    response = urlopen(url)
    data = response.read().decode("utf-8")
    return json.loads(data)


url = ("http://api.goeuro.com/api/v2/position/suggest/en/Berlin")
json_array = get_json(url)

f = open('data.txt', 'w')


for x in json_array:
    gp = x["geo_position"]
    l = gp["latitude"]
    o = gp["longitude"]
    f.write(unicode(x["_id"]).encode("utf-8") +", " +     unicode(x["name"]).encode("utf-8") + ", " + unicode(x["type"]).encode("utf-8")+ ", " + unicode(l).encode("utf-8") + ", " + unicode(o).encode("utf-8") + unicode("\n").encode("utf-8"))

f.close()

Also, what is the best way for not having an empty new line at the end of the file ?

\$\endgroup\$
2
\$\begingroup\$
  • The Python documentation recommends using with when dealing with files at the bottom of 7.2.1 of the Python tutorial, this has the benefit that you do not have to close the file yourself.

  • Although not necessary often a main function is made, so that the other functions also can be used as a module. (6.1.1. Executing modules as scripts)

  • The long line with the write statement can be split over multiple lines, you do not need the line joining character (\) in this case because, a closing bracket is still expected at the end of the line.

  • The newline problem, and simular problems can be solved with the join function of strings

I took the liberty to create an extra function and all and all i changed your code to:

from urllib2 import urlopen
import json

def get_json(url):
    response = urlopen(url)
    data = response.read().decode("utf-8")
    return json.loads(data)

def json_to_formatted_text(geo_data):
    formatted_lines = []
    for x in geo_data:
        gp = x["geo_position"]
        l = gp["latitude"]
        o = gp["longitude"]
        line = (unicode(x["_id"]).encode("utf-8")  + ", " +
                unicode(x["name"]).encode("utf-8") + ", " + 
                unicode(x["type"]).encode("utf-8") + ", " + 
                unicode(l).encode("utf-8")         + ", " + 
                unicode(o).encode("utf-8")         + 
                unicode("\n").encode("utf-8"))
        formatted_lines.append(line)
    return unicode("\n").encode("utf-8").join(formatted_lines)

def main(): 
    url = ("http://api.goeuro.com/api/v2/position/suggest/en/Berlin")
    json_array = get_json(url)
    out_text   = json_to_formatted_text(json_array)
    with open('data.txt', 'w') as f:
        f.write(out_text)

if __name__ == "__main__":
    main()
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Building on @JanKulken's answer, you could simplify the function json_to_formatted_text even more by defining a helper function to do the encoding, define a constant for the encoding of a line-break and then use str.format in that function:

def _encode(s):
    return unicode(s).encode("utf-8")

LINEBREAK = _encode("\n")


def json_to_formatted_text(geo_data):
    formatted_lines = []
    for x in geo_data:
        x["lat"] = x["geo_position"]["latitude"]
        x["lon"] = x["geo_position"]["longitude"]
        line = _encode("{name}, {type}, {lat}, {lon}\n".format(**x))
        formatted_lines.append(line)
    return LINEBREAK.join(formatted_lines)

(The other functions are the same as in his answer.)

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.