Make JSON output more readable - each pitch on one line

This commit is contained in:
Michael Winter 2026-03-24 11:04:21 +01:00
parent 4804c0c244
commit 6245ce5e27

115
src/io.py
View file

@ -11,26 +11,24 @@ from random import seed
def write_chord_sequence(seq: list["Chord"], path: str) -> None:
"""Write a chord sequence to a JSON file."""
serializable = []
for chord in seq:
chord_data = []
for pitch in chord._pitches:
chord_data.append(
{
"hs_array": list(pitch.hs_array),
"fraction": str(pitch.to_fraction()),
"cents": pitch.to_cents(),
}
)
serializable.append(chord_data)
content = json.dumps(serializable, indent=2)
content = content.replace("[[[", "[\n\t[[")
content = content.replace(", [[", ",\n\t[[")
content = content.replace("]]]", "]]\n]")
lines = ["["]
for chord_idx, chord in enumerate(seq):
lines.append(" [")
for pitch_idx, pitch in enumerate(chord._pitches):
pitch_obj = {
"hs_array": list(pitch.hs_array),
"fraction": str(pitch.to_fraction()),
"cents": pitch.to_cents(),
}
pitch_json = json.dumps(pitch_obj)
comma = "," if pitch_idx < len(chord._pitches) - 1 else ""
lines.append(f" {pitch_json}{comma}")
chord_bracket = " ]" if chord_idx == len(seq) - 1 else " ],"
lines.append(chord_bracket)
lines.append("]")
with open(path, "w") as f:
f.write(content)
f.write("\n".join(lines))
def write_chord_sequence_readable(seq: list["Chord"], path: str) -> None:
@ -70,33 +68,68 @@ def _serialize_edge_data(edge_data: dict) -> dict:
return result
def _format_chord_line(pitches: list) -> str:
"""Format a chord (list of pitch hs_arrays) as a single line."""
return json.dumps([list(p) if hasattr(p, "hs_array") else p for p in pitches])
def _format_edge_data_compact(edge_data: dict) -> dict:
"""Format edge data for compact JSON output."""
result = {}
for key, value in edge_data.items():
if hasattr(value, "hs_array"):
result[key] = list(value.hs_array)
elif isinstance(value, list) and value and hasattr(value[0], "hs_array"):
result[key] = [list(p.hs_array) for p in value]
else:
result[key] = value
return result
def write_path_steps(path: "Path", output_path: str) -> None:
"""Write path with all step data to JSON."""
steps_data = []
for i, step in enumerate(path.steps):
step_data = {
"step": i,
"source_node": [list(p.hs_array) for p in step.source_node.pitches],
"destination_node": [
list(p.hs_array) for p in step.destination_node.pitches
],
"source_chord": [list(p.hs_array) for p in step.source_chord.pitches],
"destination_chord": [
list(p.hs_array) for p in step.destination_chord.pitches
],
"transposition": list(step.transposition.hs_array)
if step.transposition
else None,
"movements": {str(k): v for k, v in step.movements.items()},
"scores": step.scores,
"normalized_scores": step.normalized_scores,
"weight": step.weight,
"edge_data": _serialize_edge_data(step.edge_data),
}
steps_data.append(step_data)
lines = ["["]
for step_idx, step in enumerate(path.steps):
lines.append(" {")
lines.append(f' "step": {step_idx},')
lines.append(
f' "source_chord": {_format_chord_line(step.source_chord.pitches)},'
)
lines.append(
f' "destination_chord": {_format_chord_line(step.destination_chord.pitches)},'
)
if step.transposition:
trans = list(step.transposition.hs_array)
lines.append(f' "transposition": {json.dumps(trans)},')
else:
lines.append(' "transposition": null,')
lines.append(
f' "movements": {json.dumps({str(k): v for k, v in step.movements.items()})},'
)
if step.scores:
lines.append(f' "scores": {json.dumps(step.scores)},')
if step.normalized_scores:
lines.append(
f' "normalized_scores": {json.dumps(step.normalized_scores)},'
)
if step.weight is not None:
lines.append(f' "weight": {step.weight},')
edge_data = _format_edge_data_compact(step.edge_data)
lines.append(f' "edge_data": {json.dumps(edge_data)}')
lines.append(" }" + ("," if step_idx < len(path.steps) - 1 else ""))
lines.append("]")
with open(output_path, "w") as f:
json.dump(steps_data, f, indent=2)
f.write("\n".join(lines))
def graph_to_dict(graph: "nx.MultiDiGraph") -> dict: