|
15 | 15 | apply_rounding, |
16 | 16 | is_in, |
17 | 17 | ) |
18 | | - |
| 18 | +from cdisc_rules_engine.enums.dataset_title_case import DatasetTitleCase |
19 | 19 | from cdisc_rules_engine.constants import NULL_FLAVORS |
20 | 20 | from cdisc_rules_engine.utilities.utils import dates_overlap, parse_date |
21 | 21 | import numpy as np |
22 | 22 | import dask.dataframe as dd |
23 | 23 | import pandas as pd |
24 | 24 | import re |
25 | 25 | import operator |
| 26 | +from titlecase import titlecase |
26 | 27 | from uuid import uuid4 |
27 | 28 | from cdisc_rules_engine.models.dataset.dask_dataset import DaskDataset |
28 | 29 | from cdisc_rules_engine.models.dataset.dataset_interface import DatasetInterface |
@@ -1073,7 +1074,7 @@ def not_contains_all(self, other_value: dict): |
1073 | 1074 | @log_operator_execution |
1074 | 1075 | @type_operator(FIELD_DATAFRAME) |
1075 | 1076 | def invalid_date(self, other_value): |
1076 | | - target = self.replace_prefix(other_value.get("target")) |
| 1077 | + target = other_value.get("target") |
1077 | 1078 | results = ~vectorized_is_valid(self.value[target]) |
1078 | 1079 | return self.value.convert_to_series(results) |
1079 | 1080 |
|
@@ -1140,7 +1141,7 @@ def is_incomplete_date(self, other_value): |
1140 | 1141 | @log_operator_execution |
1141 | 1142 | @type_operator(FIELD_DATAFRAME) |
1142 | 1143 | def is_complete_date(self, other_value): |
1143 | | - target = self.replace_prefix(other_value.get("target")) |
| 1144 | + target = other_value.get("target") |
1144 | 1145 | results = vectorized_is_complete_date(self.value[target]) |
1145 | 1146 | return self.value.convert_to_series(results) |
1146 | 1147 |
|
@@ -1944,3 +1945,39 @@ def check_order(row): |
1944 | 1945 | @type_operator(FIELD_DATAFRAME) |
1945 | 1946 | def is_not_ordered_subset_of(self, other_value: dict): |
1946 | 1947 | return ~self.is_ordered_subset_of(other_value) |
| 1948 | + |
| 1949 | + @log_operator_execution |
| 1950 | + @type_operator(FIELD_DATAFRAME) |
| 1951 | + def is_title_case(self, other_value: dict): |
| 1952 | + """ |
| 1953 | + Checks if target column values are in proper title case. |
| 1954 | + """ |
| 1955 | + target = other_value.get("target") |
| 1956 | + acronyms = DatasetTitleCase.Acronyms.value |
| 1957 | + lowercase_exceptions = DatasetTitleCase.Lowercase_Exceptions.value |
| 1958 | + |
| 1959 | + def acronym_callback(word, **kwargs): |
| 1960 | + if word.lower() in lowercase_exceptions: |
| 1961 | + return word.lower() |
| 1962 | + if any(word.upper() == acr.upper() for acr in acronyms): |
| 1963 | + return word.upper() |
| 1964 | + return None |
| 1965 | + |
| 1966 | + def check_title_case(value): |
| 1967 | + if pd.isna(value) or value == "" or value in NULL_FLAVORS: |
| 1968 | + return True |
| 1969 | + str_value = str(value).strip() |
| 1970 | + expected = titlecase(str_value, callback=acronym_callback) |
| 1971 | + expected = expected[0].upper() + expected[1:] |
| 1972 | + return str_value == expected |
| 1973 | + |
| 1974 | + results = self.value[target].apply(check_title_case) |
| 1975 | + return self.value.convert_to_series(results) |
| 1976 | + |
| 1977 | + @log_operator_execution |
| 1978 | + @type_operator(FIELD_DATAFRAME) |
| 1979 | + def is_not_title_case(self, other_value: dict): |
| 1980 | + """ |
| 1981 | + Checks if target column values are NOT in proper title case. |
| 1982 | + """ |
| 1983 | + return ~self.is_title_case(other_value) |
0 commit comments