From 381ba467105d414203bcd766b8ad03c207ec3338 Mon Sep 17 00:00:00 2001 From: Daniel Hornung <d.hornung@indiscale.com> Date: Wed, 17 Apr 2024 17:07:12 +0200 Subject: [PATCH] ENH: Filling XLSX with data of MULTIPLE_CHOICE type. --- .../table_json_conversion/fill_xlsx.py | 62 ++++++++++++++---- .../data/multiple_choice_data.json | 11 ++++ .../data/multiple_choice_data.xlsx | Bin 0 -> 6043 bytes .../data/multiple_choice_schema.json | 10 +++ .../data/multiple_choice_template.xlsx | Bin 5992 -> 5966 bytes .../table_json_conversion/test_fill_xlsx.py | 4 ++ 6 files changed, 76 insertions(+), 11 deletions(-) create mode 100644 unittests/table_json_conversion/data/multiple_choice_data.json create mode 100644 unittests/table_json_conversion/data/multiple_choice_data.xlsx diff --git a/src/caosadvancedtools/table_json_conversion/fill_xlsx.py b/src/caosadvancedtools/table_json_conversion/fill_xlsx.py index 60b5c96c..585bc6bf 100644 --- a/src/caosadvancedtools/table_json_conversion/fill_xlsx.py +++ b/src/caosadvancedtools/table_json_conversion/fill_xlsx.py @@ -206,6 +206,7 @@ class TemplateFiller: Index the sheets by all path arrays leading to them. Also create a simple column index by column type and path. + This method creates and populates the dict ``self._sheet_index``. """ self._sheet_index = {} for sheetname in self._workbook.sheetnames: @@ -227,7 +228,8 @@ class TemplateFiller: path.append(col[path_idx].value) # col_key = p2s([col[coltype_idx].value] + path) # col_index[col_key] = SimpleNamespace(column=col, col_index=col_idx) - if col[coltype_idx].value not in [ColumnType.SCALAR.name, ColumnType.LIST.name]: + if col[coltype_idx].value not in [ColumnType.SCALAR.name, ColumnType.LIST.name, + ColumnType.MULTIPLE_CHOICE.name]: continue path_str = p2s(path) @@ -308,16 +310,20 @@ out: union[dict, None] # collecting the data assert isinstance(content, list) - if len(content) > 1: - content = [ILLEGAL_CHARACTERS_RE.sub("", str(x)) for x in content] - value = ";".join(content) # TODO we need escaping of values - else: - value = content[0] - if isinstance(value, str): - value = ILLEGAL_CHARACTERS_RE.sub("", value) - path_str = p2s(path) - assert path_str not in insertables - insertables[path_str] = value + to_insert = self._try_multiple_choice(path, values=content) + if not to_insert: + if len(content) > 1: + content = [ILLEGAL_CHARACTERS_RE.sub("", str(x)) for x in content] + value = ";".join(content) # TODO we need escaping of values + else: + value = content[0] + if isinstance(value, str): + value = ILLEGAL_CHARACTERS_RE.sub("", value) + + path_str = p2s(path) + assert path_str not in insertables + to_insert = {path_str: value} + insertables.update(to_insert) if only_collect_insertables: return insertables if not current_path: # Top level returns, because there are only sheets for the children. @@ -353,6 +359,40 @@ out: union[dict, None] return None + def _try_multiple_choice(self, path: list[str], values: list[str]) -> Optional[dict[str, str]]: + """Try to create sheet content for a multiple choice property. + +Parameters +---------- +path: list[str] + The Path to this property. +values: list[str] + A list of possible choices, should be unique. + +Returns +------- +to_insert: Optional[dict[str, str]] + A path-value dict. None if this doesn't seem to be a multiple choice data set. + """ + try: + assert len(set(values)) == len(values) + to_insert = {} + found_sheet = None + for value in values: + assert isinstance(value, str) + path_str = p2s(path + [value]) + assert path_str in self._sheet_index + sheet_meta = self._sheet_index[path_str] + # All matches shall be on the same sheet + assert found_sheet is None or found_sheet == sheet_meta.sheetname + found_sheet = sheet_meta.sheetname + # Correct type + assert sheet_meta.col_type == ColumnType.MULTIPLE_CHOICE.name + to_insert[path_str] = "x" + except AssertionError: + return None + return to_insert + def fill_template(data: Union[dict, str, TextIO], template: str, result: str, validation_schema: Union[dict, str, TextIO] = None) -> None: diff --git a/unittests/table_json_conversion/data/multiple_choice_data.json b/unittests/table_json_conversion/data/multiple_choice_data.json new file mode 100644 index 00000000..1f14911e --- /dev/null +++ b/unittests/table_json_conversion/data/multiple_choice_data.json @@ -0,0 +1,11 @@ +{ + "Training": { + "name": "Super Skill Training", + "date": "2024-04-17", + "skills": [ + "Planning", + "Evaluation" + ], + "exam_types": [] + } +} diff --git a/unittests/table_json_conversion/data/multiple_choice_data.xlsx b/unittests/table_json_conversion/data/multiple_choice_data.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..28cf4007d8a1a061235863d12e5bdc5b5747f386 GIT binary patch literal 6043 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 literal 0 HcmV?d00001 diff --git a/unittests/table_json_conversion/data/multiple_choice_schema.json b/unittests/table_json_conversion/data/multiple_choice_schema.json index 75de127e..71bf0379 100644 --- a/unittests/table_json_conversion/data/multiple_choice_schema.json +++ b/unittests/table_json_conversion/data/multiple_choice_schema.json @@ -35,6 +35,16 @@ ] }, "uniqueItems": true + }, + "exam_types": { + "type": "array", + "items": { + "enum": [ + "Oral", + "Written" + ] + }, + "uniqueItems": true } } } diff --git a/unittests/table_json_conversion/data/multiple_choice_template.xlsx b/unittests/table_json_conversion/data/multiple_choice_template.xlsx index 1b4abaadb5b9a2218340f848d93cd2fbf8948908..e523506201ee7301dfa6f814e0315c01b95b08ee 100644 GIT binary patch delta 3699 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 delta 3764 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 F001)ovYr3{ diff --git a/unittests/table_json_conversion/test_fill_xlsx.py b/unittests/table_json_conversion/test_fill_xlsx.py index 946336da..1315bd9f 100644 --- a/unittests/table_json_conversion/test_fill_xlsx.py +++ b/unittests/table_json_conversion/test_fill_xlsx.py @@ -138,6 +138,10 @@ def test_fill_xlsx(): template_file=rfp("data/simple_template.xlsx"), known_good=rfp("data/simple_data_ascii_chars.xlsx"), schema=rfp("data/simple_schema.json")) + fill_and_compare(json_file=rfp("data/multiple_choice_data.json"), + template_file=rfp("data/multiple_choice_template.xlsx"), + known_good=rfp("data/multiple_choice_data.xlsx"), + schema=rfp("data/multiple_choice_schema.json")) def test_errors(): -- GitLab