Skip to content

Commit dc23bce

Browse files
committed
Fix Bag for Python3 (still 1.0.3).
1 parent 5145fbb commit dc23bce

File tree

2 files changed

+62
-9
lines changed

2 files changed

+62
-9
lines changed

histogrammar/primitives/bag.py

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,31 @@ def children(self):
239239

240240
@inheritdoc(Container)
241241
def toJsonFragment(self, suppressName):
242-
aslist = sorted(x for x in self.values.items() if x[0] != "nan")
243-
if "nan" in self.values:
244-
aslist.append(("nan", self.values["nan"]))
242+
if self.range == "N":
243+
aslist = sorted(x for x in self.values.items() if x[0] != "nan")
244+
if "nan" in self.values:
245+
aslist.append(("nan", self.values["nan"]))
246+
247+
elif self.range[0] == "N":
248+
class Sorter(object):
249+
def __init__(self, x):
250+
self.x = x
251+
def __lt__(self, other):
252+
for xi, yi in zip(self.x, other.x):
253+
if isinstance(xi, str) and isinstance(yi, float):
254+
return False
255+
elif isinstance(xi, float) and isinstance(yi, str):
256+
return True
257+
elif xi < yi:
258+
return True
259+
elif xi > yi:
260+
return False
261+
return False
262+
aslist = sorted((x for x in self.values.items()), key=lambda y: tuple(Sorter(z) for z in y))
263+
264+
else:
265+
aslist = sorted(x for x in self.values.items())
266+
245267
return maybeAdd({
246268
"entries": floatToJson(self.entries),
247269
"values": [{"w": floatToJson(n), "v": rangeToJson(v)} for v, n in aslist],
@@ -318,8 +340,34 @@ def __eq__(self, other):
318340
if len(self.values) != len(other.values):
319341
return False
320342

321-
one = sorted(x for x in self.values.items() if x[0] != "nan") + [("nan", self.values.get("nan"))]
322-
two = sorted(x for x in other.values.items() if x[0] != "nan") + [("nan", other.values.get("nan"))]
343+
if self.range != other.range:
344+
return False
345+
346+
if self.range == "N":
347+
one = sorted(x for x in self.values.items() if x[0] != "nan") + [("nan", self.values.get("nan"))]
348+
two = sorted(x for x in other.values.items() if x[0] != "nan") + [("nan", other.values.get("nan"))]
349+
350+
elif self.range[0] == "N":
351+
class Sorter(object):
352+
def __init__(self, x):
353+
self.x = x
354+
def __lt__(self, other):
355+
for xi, yi in zip(self.x, other.x):
356+
if isinstance(xi, str) and isinstance(yi, float):
357+
return False
358+
elif isinstance(xi, float) and isinstance(yi, str):
359+
return True
360+
elif xi < yi:
361+
return True
362+
elif xi > yi:
363+
return False
364+
return False
365+
one = sorted((x for x in self.values.items()), key=lambda y: tuple(Sorter(z) for z in y))
366+
two = sorted((x for x in other.values.items()), key=lambda y: tuple(Sorter(z) for z in y))
367+
368+
else:
369+
one = sorted(x for x in self.values.items())
370+
two = sorted(x for x in other.values.items())
323371

324372
for (v1, w1), (v2, w2) in zip(one, two):
325373
if isinstance(v1, basestring) and isinstance(v2, basestring):
@@ -349,7 +397,7 @@ def __eq__(self, other):
349397
else:
350398
return False
351399

352-
return isinstance(other, Bag) and self.quantity == other.quantity and numeq(self.entries, other.entries) and self.range == other.range
400+
return isinstance(other, Bag) and self.quantity == other.quantity and numeq(self.entries, other.entries)
353401

354402
def __ne__(self, other): return not self == other
355403

tests/testspec.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
1616

17+
import codecs
1718
import json
1819
import math
1920
import sys
@@ -45,16 +46,17 @@ def compare(self, x, y, name):
4546
self.assertEqual(Factory.fromJson(x), Factory.fromJson(y))
4647

4748
def runTest(self):
49+
reader = codecs.getreader("utf-8")
4850
sys.stdout.write("Downloading expected results, generated by specification {0}...\n".format(histogrammar.version.specification))
4951
try:
50-
testdata = json.load(urlopen("http://histogrammar.org/test/{0}/test-data.json".format(histogrammar.version.specification)))
52+
testdata = json.load(reader(urlopen("http://histogrammar.org/test/{0}/test-data.json".format(histogrammar.version.specification))))
5153
except Exception as err:
5254
sys.stdout.write("could not download http://histogrammar.org/test/{0}/test-data.json\nbecause of {1}: {2}\n".format(histogrammar.version.specification, err.__class__.__name__, str(err)))
5355
return
5456
try:
55-
testresults = json.load(urlopen("http://histogrammar.org/test/{0}/test-results.json".format(histogrammar.version.specification)))
57+
testresults = json.load(reader(urlopen("http://histogrammar.org/test/{0}/test-results.json".format(histogrammar.version.specification))))
5658
except Exception as err:
57-
sys.stdout.write("could not download http://histogrammar.org/test/{0}/test-results.jsonbecause of {1}: {2}\n\n".format(histogrammar.version.specification, err.__class__.__name__, str(err)))
59+
sys.stdout.write("could not download http://histogrammar.org/test/{0}/test-results.json\nbecause of {1}: {2}\n\n".format(histogrammar.version.specification, err.__class__.__name__, str(err)))
5860
return
5961

6062
for x in testdata:
@@ -71,6 +73,9 @@ def stripNames(x):
7173
stripNames(xi)
7274

7375
for testresult in testresults:
76+
testresult["expr"] = testresult["expr"].replace('"round(withholes)"', 'named("round(withholes)", lambda x: round(x["withholes"]) if math.isfinite(x["withholes"]) else x["withholes"])')
77+
testresult["expr"] = testresult["expr"].replace('"[round(withholes), 2*round(withholes), 3*round(withholes)]"', 'named("[round(withholes), 2*round(withholes), 3*round(withholes)]", lambda x: [round(x["withholes"]), 2*round(x["withholes"]), 3*round(x["withholes"])] if math.isfinite(x["withholes"]) else [x["withholes"], x["withholes"], x["withholes"]])')
78+
7479
sys.stderr.write(testresult["expr"] + "\n")
7580

7681
zero = testresult["zero-named"]

0 commit comments

Comments
 (0)