JWONTSEEIT
JWONTSEEIT

Reputation: 5

Why will this json data not load?

Trying to import dictionaries from an external Json file using json.loads, however when I do this I am met with an error message.

import json
import random

winner = "None"
winners = 0

class player:
    def __init__(self, playernum):
        self.playernum = playernum
        self.score = random.randint(1,6)
        self.name = "foo"
player1 = player(1)
player2 = player(2)

if player1.score > player2.score:
    winner = player1.name
    winners = player1.score
elif player2.score > player1.score:
    winner = player2.name
    winners = player2.score

with open("highscores.txt", "a") as f:
  json.dump({winner : winners}, f)
f.close()

with open("highscores.txt", "r") as f:
  scores = json.load(f)
f.close()

print(scores)

Highscores.txt currently contains 7 dictionaries; {"Daniel": 71}{"Jonathan": 26}{"Jonathan": 58}{"Daniel": 90}{"Jonathan": 57}{"Jonathan": 80}{"Jonathan": 50}

Shouldn't it print out the file, which should be comprised of winner:winners dictionaries? Instead, I get this error message:

Traceback (most recent call last):
  File "C:/Users/jonat/AppData/Local/Programs/Python/Python36-32/neacode.py", line 119, in <module>
    scores = json.load(f)

  File "C:\Users\jonat\AppData\Local\Programs\Python\Python36-32\lib\json\__init__.py", line 299, in load
    parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw)
  File "C:\Users\jonat\AppData\Local\Programs\Python\Python36-32\lib\json\__init__.py", line 354, in loads
    return _default_decoder.decode(s)
  File "C:\Users\jonat\AppData\Local\Programs\Python\Python36-32\lib\json\decoder.py", line 342, in decode
    raise JSONDecodeError("Extra data", s, end)
json.decoder.JSONDecodeError: Extra data: line 1 column 15 (char 14)

Why?

Upvotes: 0

Views: 56

Answers (1)

C.Nivs
C.Nivs

Reputation: 13106

It's because you are appending dictionaries to a file, which is not valid json syntax:

from io import StringIO
import json

s = '''{"a": 1}
{"b": 2}
{"c": 3}'''

fh = StringIO(s)
json.load(fh) # JSONDecodeError

Furthermore, using json.dump in a file opened in append ('a') mode won't include newlines, which yields even worse non-json. To handle this, I'd change how you append to the file:

with open('highscores.txt', 'a') as fh:
    obj = json.dumps({winner: winners})+'\n' # note the added newline here
    fh.write(obj)

This will allow you to read in the file line by line:

with open('highscores.txt', 'r') as fh:
    scores = [json.loads(line.strip()) for line in fh]

print(scores)

Also, note that you don't have to call fh.close() as the with statement will take care of that for you

Upvotes: 1

Related Questions