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: def write_chord_sequence(seq: list["Chord"], path: str) -> None:
"""Write a chord sequence to a JSON file.""" """Write a chord sequence to a JSON file."""
serializable = [] lines = ["["]
for chord in seq: for chord_idx, chord in enumerate(seq):
chord_data = [] lines.append(" [")
for pitch in chord._pitches: for pitch_idx, pitch in enumerate(chord._pitches):
chord_data.append( pitch_obj = {
{ "hs_array": list(pitch.hs_array),
"hs_array": list(pitch.hs_array), "fraction": str(pitch.to_fraction()),
"fraction": str(pitch.to_fraction()), "cents": pitch.to_cents(),
"cents": pitch.to_cents(), }
} pitch_json = json.dumps(pitch_obj)
) comma = "," if pitch_idx < len(chord._pitches) - 1 else ""
serializable.append(chord_data) lines.append(f" {pitch_json}{comma}")
chord_bracket = " ]" if chord_idx == len(seq) - 1 else " ],"
content = json.dumps(serializable, indent=2) lines.append(chord_bracket)
content = content.replace("[[[", "[\n\t[[") lines.append("]")
content = content.replace(", [[", ",\n\t[[")
content = content.replace("]]]", "]]\n]")
with open(path, "w") as f: 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: 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 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: def write_path_steps(path: "Path", output_path: str) -> None:
"""Write path with all step data to JSON.""" """Write path with all step data to JSON."""
steps_data = [] lines = ["["]
for i, step in enumerate(path.steps): for step_idx, step in enumerate(path.steps):
step_data = { lines.append(" {")
"step": i, lines.append(f' "step": {step_idx},')
"source_node": [list(p.hs_array) for p in step.source_node.pitches],
"destination_node": [ lines.append(
list(p.hs_array) for p in step.destination_node.pitches f' "source_chord": {_format_chord_line(step.source_chord.pitches)},'
], )
"source_chord": [list(p.hs_array) for p in step.source_chord.pitches], lines.append(
"destination_chord": [ f' "destination_chord": {_format_chord_line(step.destination_chord.pitches)},'
list(p.hs_array) for p in step.destination_chord.pitches )
],
"transposition": list(step.transposition.hs_array) if step.transposition:
if step.transposition trans = list(step.transposition.hs_array)
else None, lines.append(f' "transposition": {json.dumps(trans)},')
"movements": {str(k): v for k, v in step.movements.items()}, else:
"scores": step.scores, lines.append(' "transposition": null,')
"normalized_scores": step.normalized_scores,
"weight": step.weight, lines.append(
"edge_data": _serialize_edge_data(step.edge_data), f' "movements": {json.dumps({str(k): v for k, v in step.movements.items()})},'
} )
steps_data.append(step_data)
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: 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: def graph_to_dict(graph: "nx.MultiDiGraph") -> dict: