Python Forum
Object of type Scoreboard is not JSON serializable
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Object of type Scoreboard is not JSON serializable
#1
Object of type Scoreboard is not JSON serializable

IS ANY OTHER WAY TO serialize this OBJECT ... ? trying a scoreboard for a game...

>>> %Run snake-points-pause-sounds-highscores2.py
pygame 1.9.6
Hello from the pygame community. https://www.pygame.org/contribute.html
Traceback (most recent call last):
File "F:\OneDrive\OneDrive\macOS_MBP2016\2019mbp\Clients\Snake - PyGame\snake-points-pause-sounds-highscores2.py", line 424, in <module>
drawGameOver(surface, data.username, data.points)
File "F:\OneDrive\OneDrive\macOS_MBP2016\2019mbp\Clients\Snake - PyGame\snake-points-pause-sounds-highscores2.py", line 115, in drawGameOver
board = scoreRecord(username, points)
File "F:\OneDrive\OneDrive\macOS_MBP2016\2019mbp\Clients\Snake - PyGame\snake-points-pause-sounds-highscores2.py", line 355, in scoreRecord
serialize("hightscores.txt", board)
File "F:\OneDrive\OneDrive\macOS_MBP2016\2019mbp\Clients\Snake - PyGame\snake-points-pause-sounds-highscores2.py", line 285, in serialize
json.dump(players, f)
File "C:\Users\lwdls\Thonny\lib\json\__init__.py", line 179, in dump
for chunk in iterable:
File "C:\Users\lwdls\Thonny\lib\json\encoder.py", line 438, in _iterencode
o = _default(o)
File "C:\Users\lwdls\Thonny\lib\json\encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type Scoreboard is not JSON serializable


# hghscores - start

def deserialize(fileName):
    exists = os.path.isfile(fileName)
    if exists:
        # Store configuration file values
        f = open(fileName, 'r')
        board = json.load(f)
        f.close()    
    else:
        # Keep presets
        board = Scoreboard()
        
    return board


def serialize(fileName, players):
    f = open(fileName, 'w')
    json.dump(players, f)
    f.close()


class GameEntry:
  """Represents one entry of a list of high scores."""

  def __init__(self, name, score):
    """Create an entry with given name and score."""
    self._name = name
    self._score = score

  def get_name(self):
    """Return the name of the person for this entry."""
    return self._name
    
  def get_score(self):
    """Return the score of this entry."""
    return self._score

  def __str__(self):
    """Return string representation of the entry."""
    return '({0}, {1})'.format(self._name, self._score) # e.g., '(Bob, 98)'


class Scoreboard:
  """Fixed-length sequence of high scores in nondecreasing order."""

  def __init__(self, capacity=10):
    """Initialize scoreboard with given maximum capacity.

    All entries are initially None.
    """
    self._board = [None] * capacity        # reserve space for future scores
    self._n = 0                            # number of actual entries

  def __getitem__(self, k):
    """Return entry at index k."""
    return self._board[k]

  def __str__(self):
    """Return string representation of the high score list."""
    return '\n'.join(str(self._board[j]) for j in range(self._n))

  def add(self, entry):
    """Consider adding entry to high scores."""
    score = entry.get_score()

    # Does new entry qualify as a high score?
    # answer is yes if board not full or score is higher than last entry
    good = self._n < len(self._board) or score > self._board[-1].get_score()

    if good:
      if self._n < len(self._board):        # no score drops from list
        self._n += 1                        # so overall number increases

      # shift lower scores rightward to make room for new entry
      j = self._n - 1
      while j > 0 and self._board[j-1].get_score() < score:
        self._board[j] = self._board[j-1]   # shift entry from j-1 to j
        j -= 1                              # and decrement j
      self._board[j] = entry                # when done, add new entry


def scoreRecord(username, points):
    board = deserialize("hightscores.txt")

    entry = GameEntry(username, points)
    board.add(entry)
            
    serialize("hightscores.txt", board)
        
    return board
       
Reply
#2
json.dump takes non mandatory param encoder
Use https://docs.python.org/3/library/json.h...SONEncoder to customize encoder
Reply
#3
In my case... of custom object of type class Scoreboard

what can try / use ???

or is better use
Writing Your Own Serializer
???
Reply
#4
Ok,I've just created my own class SuperClass. Do you know, how to convert it's object into JSON? Of course, nobody knows except me. You have to write your own serializer. I can suggest solution like this:

import json


class Foo(object):

    def __init__(self):
        self.a = 1
        self.b = 1

    def __json__(self):
        return dict(a=self.a, b=self.b)


class MyUniversalEncoder(json.JSONEncoder):
    def default(self, obj):
        if hasattr(obj, "__json__"):
            return obj.__json__()
        return json.JSONEncoder.default(self, obj)


f = Foo()
print json.dumps(f, cls=MyUniversalEncoder)
Reply
#5
I solve the problem using Scoreboard object and my own serializer/deserializer

text file(storage.txt) is like

Player1username, 1600
Player3username, 800
Player2username, 500
....
....

this i ask is
is any python 3 serializer/deserializer build-in func to store the object Scoreboard in file txt or binary file ... ?
Reply
#6
Quote:is any python 3 serializer/deserializer build-in func to store the object Scoreboard in file txt

What do you think json.dump does?
Reply
#7
Look at jsonpickle.
A quick example and i have removed getter/setter which in not popular or not needed for simple simple attribute access.
For more advance attribute access that return a value can use @property.
import jsonpickle

class GameEntry:
  """Represents one entry of a list of high scores."""
  def __init__(self, name, score):
    """Create an entry with given name and score."""
    self.name = name
    self.score = score

  def __str__(self):
    """Return string representation of the entry."""
    return f'({self.name}, {self.score})' # e.g., '(Bob, 98)'

obj = GameEntry('Bob', 98)
frozen = jsonpickle.encode(obj)

# To disk
with open('score.json', 'w') as j_out:
    print(frozen, file=j_out)

# From disk
with open('score.json') as j:
    frozen_obj = jsonpickle.decode(j.read())
Test frozen_obj:
>>> frozen_obj.name
'Bob'
>>> frozen_obj.score
98

>>> print(frozen_obj)
(Bob, 98)
Reply
#8
(Jul-31-2019, 10:10 AM)fishhook Wrote:
Quote:is any python 3 serializer/deserializer build-in func to store the object Scoreboard in file txt

What do you think json.dump does?

If I want save... use binary or text file ?
Reply
#9
(Jul-31-2019, 04:41 PM)lsepolis123 Wrote:
(Jul-31-2019, 10:10 AM)fishhook Wrote: What do you think json.dump does?

If I want save... use binary or text file ?

It looks like to be impossible to save python object to text.
class Foo:
   pass

a = Foo()

def log(text):
    print(text)

a.log = log

a.log("foo")
To save "a" object to a file it is required to save the byte-code of "log" function either. To save the object completely there is "pickle" and "cPickle" packages. Both of them make binary from python object. But assume, that you need to pass a data from web-server to web-client. You can't use pickle for that because JavaScript knows nothing about python's bytecode and it's impossible to convert python class to JS class. For that case, another approach is applied. You have to convert your python object to some format, but the result can only contain data, not methods. So that type of serialization can be text(JSON, YAML, XML) or binary(protobuf, MessagePack). Choose the format you need.
Reply
#10
def deserialize(fileName):
    # From disk
    with open(fileName) as j:
        frozen_obj = jsonpickle.decode(j.read())
    return frozen_obj

def serialize(fileName, frozen):
    # To disk
    with open(fileName, 'w') as j_out:
        print(frozen, file=j_out)
    


if __name__ == '__main__':
  for e in (
    ('Rob', 750), ('Mike',1105), ('Rose', 590), ('Jill', 740),
    ('Jack', 510), ('Anna', 660), ('Paul', 720), ('Bob', 400),
    ):
    ge = GameEntry(e[0], e[1])
    frozen = jsonpickle.encode(ge)

    serialize("hightscores.json", frozen)

// how to append with jsonpickle... above add only last one... well? Also How get all users back, after append all in json to file?
// hightscores.json
{"_name": "Bob", "_score": 400, "py/object": "__main__.GameEntry"}
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  declaring object parameters with type JonWayn 2 856 Dec-13-2022, 07:46 PM
Last Post: JonWayn
  Help to make a shuffleboard scoreboard Slett1 1 1,107 Apr-28-2022, 06:18 PM
Last Post: deanhystad
  Deserialize Complex Json to object using Marshmallow tlopezdh 2 2,085 Dec-09-2021, 06:44 PM
Last Post: tlopezdh
Star Type Error: 'in' object is not callable nman52 3 3,328 May-01-2021, 11:03 PM
Last Post: nman52
  finding and deleting json object GrahamL 1 4,801 Dec-10-2020, 04:11 PM
Last Post: bowlofred
  Serializable JarredAwesome 4 2,168 Nov-19-2020, 11:50 PM
Last Post: JarredAwesome
  TypeError: 'type' object is not subscriptable Stef 1 4,440 Aug-28-2020, 03:01 PM
Last Post: Gribouillis
  isinstance() always return true for object type check Yoki91 2 2,498 Jul-22-2020, 06:52 PM
Last Post: Yoki91
  AttributeError: type object 'FunctionNode' has no attribute '_TestValidateFuncLabel__ binhduonggttn 0 2,219 Feb-19-2020, 11:29 AM
Last Post: binhduonggttn
  Type hinting - return type based on parameter micseydel 2 2,425 Jan-14-2020, 01:20 AM
Last Post: micseydel

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020