Browse Source

Add point saving to JSON - still needs to be linked to file menu

tb-init-ui-render
Taylor Bockman 5 years ago
parent
commit
fa158cd0b3
  1. 45
      clusterview/point_manager.py
  2. 45
      clusterview/points.py
  3. 78
      tests/test_point_manager.py

45
clusterview/point_manager.py

@ -1,3 +1,7 @@
import json
from .points import PointSet
class PointManager():
"""
A state class that represents the absolute state of the
@ -5,3 +9,44 @@ class PointManager():
"""
point_set = None
@staticmethod
def load(location):
"""
Loads the JSON file from the location and populates point_set
with it's contents.
@param location The location of the JSON file.
"""
with open(location) as json_file:
data = json.load(json_file)
PointManager.point_set = PointSet(data['point_size'],
data['viewport_width'],
data['viewport_height'])
for point in data['points']:
PointManager.point_set.add_point(point['x'], point['y'])
@staticmethod
def save(location):
"""
Persists the point_set as a JSON file at location.
@param location The persistence location.
"""
data = {}
data['point_size'] = PointManager.point_set.point_size
data['viewport_width'] = PointManager.point_set.viewport_width
data['viewport_height'] = PointManager.point_set.viewport_height
data['points'] = []
for p in PointManager.point_set.points:
data['points'].append({
'x': p.x,
'y': p.y
})
with open(location, 'w') as out_file:
json.dump(data, out_file)

45
clusterview/points.py

@ -109,9 +109,18 @@ class Point:
return hash((self.__x, self.__y, self.__point_size))
def __repr__(self):
return "POINT<X :{} Y: {} SIZE: {}>".format(self.__x,
self.__y,
self.__point_size)
# For some reason I had to split this instead of using one giant
# string chained with `+` inside of `()`.
s = "<POINT "
s += "X: {} | Y: {} | ".format(self.__x, self.__y)
s += "SIZE: {} | ".format(self.__point_size)
s += "VIEWPORT_WIDTH: {} |".format(self.__viewport_width)
s += "VIEWPORT_HEIGHT: {}".format(self.__viewport_height)
s += ">"
return s
def select(self):
"""
Selects the point.
@ -182,6 +191,36 @@ class PointSet:
self.__viewport_width = viewport_width
self.__viewport_height = viewport_height
def __eq__(self, other):
# We are forced to convert other.points from generator to a set to
# check equality on the sets. This could possibly get very slow
# for large numbers of points.
attributes_equal = True
other_points = set(other.points)
attributes_equal = (attributes_equal and
(len(self.__points) == len(other_points)))
for p in self.__points:
attributes_equal = (attributes_equal and
(self.__attributes[p] == other.attributes(p)))
return (self.__points == other_points and
attributes_equal and
self.__point_size == other.point_size and
self.__viewport_width == other.viewport_width and
self.__viewport_height == other.viewport_height)
def __repr__(self):
s = []
for p in self.__points:
s.append(str(p))
return ",".join(s)
@property
def points(self):
"""

78
tests/test_point_manager.py

@ -0,0 +1,78 @@
import json
import os
import pytest
from clusterview.points import PointSet
from clusterview.point_manager import PointManager
@pytest.fixture(autouse=True)
def setup():
p = PointSet(8, 100, 100)
p.add_point(4, 4)
p.add_point(9, 10)
p.add_point(30, 40)
PointManager.point_set = p
def test_load(tmpdir):
test = ("{\n"
"\"point_size\": 8,\n"
"\"viewport_height\": 100,\n"
"\"viewport_width\": 100,\n"
"\"points\":[\n"
"{\"x\": 8, \"y\": 8},"
"{\"x\": 30, \"y\": 50}"
"]\n"
"}")
p = tmpdir.mkdir("test_data").join("test.json")
p.write(test)
expected = PointSet(8, 100, 100)
expected.add_point(8, 8)
expected.add_point(30, 50)
PointManager.load(p)
print(PointManager.point_set)
# The fixture point_set inside the singleton PointManager should be
# overwritten.
assert PointManager.point_set == expected
def test_save(tmpdir):
d = tmpdir.mkdir("test_data").join("save.json")
PointManager.save(d)
expected_str = ("{"
"\"point_size\": 8,"
"\"viewport_height\": 100,"
"\"viewport_width\": 100,"
"\"points\":["
"{\"x\": 4, \"y\": 4},"
"{\"x\": 9, \"y\": 10},"
"{\"x\": 30, \"y\": 40}"
"]"
"}")
with open(d) as f:
expected = json.loads(expected_str)
actual = json.load(d)
# Since the JSON module converts the `points` key to
# a list of dicts, we need to do manual comparison
# to get around the problem of list equality when we
# really want a set of Points.
assert actual["point_size"] == expected["point_size"]
assert actual["viewport_width"] == expected["viewport_width"]
assert actual["viewport_height"] == expected["viewport_height"]
assert len(actual["points"]) == len(expected["points"])
for p in actual["points"]:
assert p in expected["points"]
Loading…
Cancel
Save