diff --git a/doc/sinter_api.md b/doc/sinter_api.md index a29c5b19..f91a8176 100644 --- a/doc/sinter_api.md +++ b/doc/sinter_api.md @@ -852,7 +852,7 @@ def to_csv_line( >>> print(sinter.CSV_HEADER) shots, errors, discards, seconds,decoder,strong_id,json_metadata,custom_counts >>> print(stat.to_csv_line()) - 22, 3, 0, 5,pymatching,test,"{""a"":[1,2,3]}", + 22, 3, 0, 5.00,pymatching,test,"{""a"":[1,2,3]}", """ ``` diff --git a/glue/sample/src/sinter/_data/_anon_task_stats.py b/glue/sample/src/sinter/_data/_anon_task_stats.py index 60fee918..42281c07 100644 --- a/glue/sample/src/sinter/_data/_anon_task_stats.py +++ b/glue/sample/src/sinter/_data/_anon_task_stats.py @@ -1,6 +1,7 @@ import collections import dataclasses from typing import Counter, Union, TYPE_CHECKING +import numpy as np if TYPE_CHECKING: from sinter._data._task_stats import TaskStats @@ -34,16 +35,16 @@ class AnonTaskStats: custom_counts: Counter[str] = dataclasses.field(default_factory=collections.Counter) def __post_init__(self): - assert isinstance(self.errors, int) - assert isinstance(self.shots, int) - assert isinstance(self.discards, int) - assert isinstance(self.seconds, (int, float)) + assert isinstance(self.errors, (int, np.integer)) + assert isinstance(self.shots, (int, np.integer)) + assert isinstance(self.discards, (int, np.integer)) + assert isinstance(self.seconds, (int, float, np.integer, np.floating)) assert isinstance(self.custom_counts, collections.Counter) assert self.errors >= 0 assert self.discards >= 0 assert self.seconds >= 0 assert self.shots >= self.errors + self.discards - assert all(isinstance(k, str) and isinstance(v, int) for k, v in self.custom_counts.items()) + assert all(isinstance(k, str) and isinstance(v, (int, np.integer)) for k, v in self.custom_counts.items()) def __repr__(self) -> str: terms = [] diff --git a/glue/sample/src/sinter/_data/_csv_out.py b/glue/sample/src/sinter/_data/_csv_out.py index 2feb0fa2..535b9abe 100644 --- a/glue/sample/src/sinter/_data/_csv_out.py +++ b/glue/sample/src/sinter/_data/_csv_out.py @@ -36,6 +36,9 @@ def csv_line(*, separators=(',', ':'), sort_keys=True) if custom_counts: + # Ensure all custom_counts values are integers before dumping to JSON + for k in custom_counts: + custom_counts[k] = int(custom_counts[k]) custom_counts = escape_csv( json.dumps(custom_counts, separators=(',', ':'), diff --git a/glue/sample/src/sinter/_data/_task_stats.py b/glue/sample/src/sinter/_data/_task_stats.py index 4d846e89..f184e94d 100644 --- a/glue/sample/src/sinter/_data/_task_stats.py +++ b/glue/sample/src/sinter/_data/_task_stats.py @@ -4,7 +4,7 @@ from typing import Optional from typing import Union from typing import overload - +import numpy as np from sinter._data._anon_task_stats import AnonTaskStats from sinter._data._csv_out import csv_line @@ -71,10 +71,10 @@ class TaskStats: custom_counts: Counter[str] = dataclasses.field(default_factory=collections.Counter) def __post_init__(self): - assert isinstance(self.errors, int) - assert isinstance(self.shots, int) - assert isinstance(self.discards, int) - assert isinstance(self.seconds, (int, float)) + assert isinstance(self.errors, (int, np.integer)) + assert isinstance(self.shots, (int, np.integer)) + assert isinstance(self.discards, (int, np.integer)) + assert isinstance(self.seconds, (int, float, np.integer, np.floating)) assert isinstance(self.custom_counts, collections.Counter) assert isinstance(self.decoder, str) assert isinstance(self.strong_id, str) @@ -83,7 +83,7 @@ def __post_init__(self): assert self.discards >= 0 assert self.seconds >= 0 assert self.shots >= self.errors + self.discards - assert all(isinstance(k, str) and isinstance(v, int) for k, v in self.custom_counts.items()) + assert all(isinstance(k, str) and isinstance(v, (int, np.integer)) for k, v in self.custom_counts.items()) def with_edits( self, @@ -190,13 +190,13 @@ def to_csv_line(self) -> str: >>> print(sinter.CSV_HEADER) shots, errors, discards, seconds,decoder,strong_id,json_metadata,custom_counts >>> print(stat.to_csv_line()) - 22, 3, 0, 5,pymatching,test,"{""a"":[1,2,3]}", + 22, 3, 0, 5.00,pymatching,test,"{""a"":[1,2,3]}", """ return csv_line( - shots=self.shots, - errors=self.errors, - seconds=self.seconds, - discards=self.discards, + shots=int(self.shots), + errors=int(self.errors), + seconds=float(self.seconds), + discards=int(self.discards), strong_id=self.strong_id, decoder=self.decoder, json_metadata=self.json_metadata, diff --git a/glue/sample/src/sinter/_data/_task_stats_test.py b/glue/sample/src/sinter/_data/_task_stats_test.py index 4060c2f1..79f456f2 100644 --- a/glue/sample/src/sinter/_data/_task_stats_test.py +++ b/glue/sample/src/sinter/_data/_task_stats_test.py @@ -29,7 +29,7 @@ def test_to_csv_line(): discards=4, seconds=5, ) - assert v.to_csv_line() == str(v) == ' 22, 3, 4, 5,pymatching,test,"{""a"":[1,2,3]}",' + assert v.to_csv_line() == str(v) == ' 22, 3, 4, 5.00,pymatching,test,"{""a"":[1,2,3]}",' def test_to_anon_stats():