diff --git a/kloppy/infra/serializers/code/sportscode.py b/kloppy/infra/serializers/code/sportscode.py index c4ccb8c10..f259bd7f3 100644 --- a/kloppy/infra/serializers/code/sportscode.py +++ b/kloppy/infra/serializers/code/sportscode.py @@ -121,21 +121,31 @@ def serialize(self, dataset: CodeDataset) -> bytes: code_.text = code.code for group, text in code.labels.items(): - # Labels can be in two formats: - # {"name": "value"} or {"name": True} - label = etree.SubElement(instance, "label") - if isinstance(text, bool): + # Labels can be in three formats: + # {"name": "value"} or {"name": True} or {"name": ["value1", "value2"]} + + # Handle lists of values (multiple labels for same group) + if isinstance(text, list): + for text_item in text: + # Skip boolean values in lists + if not isinstance(text_item, bool): + label = etree.SubElement(instance, "label") + group_ = etree.SubElement(label, "group") + group_.text = str(group) + text_ = etree.SubElement(label, "text") + text_.text = str(text_item) + elif isinstance(text, bool): if not text: raise SerializationError( f"You are not allowed to pass a False value for {group}" ) - + label = etree.SubElement(instance, "label") text_ = etree.SubElement(label, "text") text_.text = group else: + label = etree.SubElement(instance, "label") group_ = etree.SubElement(label, "group") group_.text = str(group) - text_ = etree.SubElement(label, "text") text_.text = str(text) diff --git a/kloppy/tests/test_xml.py b/kloppy/tests/test_xml.py index bd663285e..0f464c569 100644 --- a/kloppy/tests/test_xml.py +++ b/kloppy/tests/test_xml.py @@ -1,4 +1,5 @@ from datetime import timedelta +from dataclasses import replace from pandas import DataFrame from pandas._testing import assert_frame_equal @@ -126,3 +127,40 @@ def test_correct_serialization(self, base_dir): """ expected_output = bytes(expected_output, "utf-8") assert output == expected_output + + def test_serialization_with_multiple_labels_per_group(self, base_dir): + dataset = sportscode.load(base_dir / "files/code_xml.xml") + + # Create a modified code with multiple labels for the same group + modified_code = replace( + dataset.codes[0], + labels={ + "Team": ["Henkie", "Klaas"], + "SCORE": ["5-6", "s-1", "s+1"], + "Single": "Value", + }, + ) + + # Create a new dataset with only the modified code + modified_dataset = replace(dataset, records=[modified_code]) + + serializer = SportsCodeSerializer() + output = serializer.serialize(modified_dataset) + + # Verify the output contains multiple label elements for the same group + output_str = output.decode("utf-8") + + # Should have 2 Team labels + assert output_str.count("Team") == 2 + assert "Henkie" in output_str + assert "Klaas" in output_str + + # Should have 3 SCORE labels + assert output_str.count("SCORE") == 3 + assert "5-6" in output_str + assert "s-1" in output_str + assert "s+1" in output_str + + # Should have 1 Single label + assert output_str.count("Single") == 1 + assert "Value" in output_str diff --git a/kloppy/utils.py b/kloppy/utils.py index b88a3100a..ef2d514ee 100644 --- a/kloppy/utils.py +++ b/kloppy/utils.py @@ -30,7 +30,7 @@ def performance_logging( took = (time.time() - start) * 1000 extra = "" if counter is not None: - extra = f" ({int(counter / took * 1000)}items/sec)" + extra = f" ({counter / took * 1000:.1f}items/sec)" unit = "ms" if took < 0.1: